既知のバグが解決されたときに、新しいバグが別の場所に表示される原因は何ですか?


14

議論の中で、私の同僚の一人は、バグを解決しようとしている間、彼の現在のプロジェクトにいくつかの困難があると言いました。「1つのバグを解決すると、他の何かが他の場所で機能しなくなります」と彼は言いました。

私はこれがどのように起こるのか考え始めましたが、それを理解することはできません。

  • 疲れていたり眠すぎたりして、正しく作業できず、作業中のコードの一部を全体的に見ることができない場合、同様の問題が発生することがあります。ここで、問題は数日または数週間にあるようで、私の同僚の焦点とは関係ありません。
  • また、この問題は、非常に管理の行き届いていない非常に大きなプロジェクトで発生することも想像できます。チームメイトは、誰が何を行い、他の作業にどのような影響を与えるかがわからないのです。これもここでは当てはまりません。開発者が1人だけのかなり小さなプロジェクトです。
  • また、古い、メンテナンスが不十分でドキュメント化されていないコードベースの問題になる可能性があります。変更の結果を本当に想像できる唯一の開発者は、数年前に会社を去りました。ここでは、プロジェクトが始まったばかりで、開発者は誰のコードベースも使用していません。

それで、彼の仕事に集中し続ける一人の開発者によって書かれた新鮮な小さなコードベースで、そのような問題の原因は何でしょうか?

何が役立ちますか?

  • 単体テスト(なし)
  • 適切なアーキテクチャー(コードベースにはアーキテクチャーがまったくなく、予備的な考えなしに作成されたと確信しています)、リファクタリング全体が必要ですか?
  • ペアプログラミング?
  • 他に何か?

14
ああ、古き良き「カスケードの失敗の波」デザインパターン。:-)
ブライアンノブラウチ

1
私はそれを一枚の接触の中の泡にたとえました。押し下げると、他の場所にポップアップします。コーディングが良くなればなるほど、見えなくなる
johnc

2
補足として、私はまさに組み込みシステムでそれを持っていました。問題を修正するために関数呼び出しを追加しました。その関数呼び出しはスタックに対して多すぎたため(マイクロコントローラーにはスタックオーバーフローの検出がありませんでした)、メモリに他のランダムなものを書き込みました。そのため、このことは、開発者が1人だけで、優れたアーキテクチャを持つ小さなコードベースで発生する可能性があります。
risingDarkness

...それはデバッグするのが悪夢でした。
risingDarkness

回答:


38

フォーカス、プロジェクトのサイズ、ドキュメント、またはその他のプロセスの問題とはあまり関係ありません。そのような問題は通常、設計における過剰な結合の結果であり、変更を特定することは非常に困難です。


15
これは貧弱な回帰テストまたは
ゼロ

3
確かに、@ Ryathal、回帰テストではこうした種類のバグを防ぐことはできませんが、すぐにお知らせください。
カールビーレフェルト

バグについてすぐに知っていれば(たとえば、バグを作成してから数分以内に)、変更を取り消すことができ、変更が発生しなかったように見せかけることができます。
-bdsl

14

原因の1つは、ソフトウェアのコンポーネント間の密結合です。コンポーネント間に単純で明確に定義されたインターフェイスがない場合、コードの一部にわずかな変更を加えても、他の部分に予期しない副作用が生じる可能性がありますコード。

例として、最近、アプリケーションにGUIコンポーネントを実装するクラスに取り組んでいました。数週間、新しいバグが報告され、それらを修正し、新しいバグが別の場所に現れました。クラスが大きくなりすぎて、あまりにも多くのことを行い、多くのメソッドが適切に機能するために正しいシーケンスで呼び出される他のメソッドに依存していることに気付きました。

最新の3つのバグを修正する代わりに、いくつかの強力なリファクタリングを行いました。コンポーネントをメインクラスとMVCクラス(3つの追加クラス)に分割します。このようにして、コードを小さくシンプルな部分に分割し、より明確なインターフェースを定義する必要がありました。リファクタリング後、すべてのバグが解決され、新しいバグは報告されませんでした。


7

あるバグが別のバグを隠すのは簡単です。バグ「A」の結果、入力を処理するために間違った関数が呼び出されたとします。バグ「A」が修正されると、突然正しい関数が呼び出されますが、これはテストされたことはありません。


5

さて、直接的な原因は、2つの不正が権利を作成すること、または少なくとも明らかではないことです。コードの一部は、他の部分の不正な動作を補正しています。または、最初の部分がそのように「間違っていない」場合、コードが変更されたときに違反している2つの部分の間に書面による合意がいくつかあります。

たとえば、関数AとBがいくつかの量に対してゼロベースの規則を使用しているため、それらは正しく連携しますが、Cは1を使用すると仮定します。

より深い問題は、個々の部品の正確性の独立した検証の欠如です。ユニットテストはこれに対処するように設計されています。また、適切な入力の仕様としても機能します。たとえば、適切なテストセットにより、関数AとBが0ベースの入力とC 1ベースの入力を期待していることが明らかになります。

仕様を正しくすることは、プロジェクトのニーズに応じて、公式文書からコード内の適切なコメントまで、他の方法でも実行できます。重要なのは、各コンポーネントが何を期待し、何を約束しているかを理解することです。そのため、矛盾を見つけることができます。

優れたアーキテクチャは、コードを理解するという問題を助け、これを容易にします。ペアプログラミングは、そもそもバグを回避したり、バグをより迅速に見つけたりするのに役立ちます。

お役に立てれば。


5

密結合、テストの欠如、これらはおそらく最も一般的な犯人です。基本的に、一般的な問題は見掛け倒しの基準と手順です。もう1つは、正しい動作でしばらく運が良かったという誤ったコードです。memcpyLinus Torvaldsのバグを考えてください。実装を変更すると、ソースと宛先が重複しmemcpyて使用されるはずの場所で使用されるクライアントのバグが発生します(発生しません)memmove


4

これらの「新しい」バグは、実際には「新しい」バグではないようです。壊れた他のコードが実際に修正されるまで、それらは問題ではありませんでした。言い換えれば、あなたの同僚は、彼が実際にずっと2つのバグを抱えていたことに気付いていません。壊れていることが証明されていないコードが壊れていなければ、他のコードが実際に修正されていれば、失敗することはありませんでした。

どちらの場合でも、より良い自動化されたテスト計画が役立つかもしれません。同僚が現在のコードベースを単体テストする必要があるようです。将来の回帰テストでは、既存のコードが引き続き機能することを確認します。


0

改善あなたの自動テストレジメンのを。コードの変更をコミットする前に、常にテストの完全なセットを実行します。そうすれば、変更の有害な影響を検出できます。


0

テストが間違っていたときにこれに遭遇しました。テストでは、!正しいという特定の許可状態をチェックしました。コードを更新し、許可テストを実行しました。動いた。その後、すべてのテストを実行しました。チェックされたリソースを使用した他のすべてのテストは失敗しました。テストと権限チェックを修正しましたが、最初は少しパニックがありました。

一貫性のない仕様も発生します。そうすれば、1つのバグを修正しても別のバグが作成されることがほぼ保証されます(仕様の特定の部分がプロジェクトの後半まで実行されない場合に興奮します)。


0

完全な製品があると想像してください。次に、何か新しいものを追加すると、すべてがうまくいくように見えますが、新しい機能を動作させるために変更するコードに依存する何か他のものを壊しました。コードを変更しなくても、既存の機能を追加するだけで、他の何かを壊す可能性があります。

基本的に、あなたはほとんど自分自身に答えました:

  • 疎結合
  • テストの欠如

TDDの原則を(少なくとも新しい機能に)適合させ、起こりうるすべての状態をテストしてみてください。

ペアプログラミングは優れていますが、常に「利用可能」とは限りません(時間、お金、両方)。ただし、特にレビューにテストスイートが含まれている場合は、1日1回、1週間に1回、一連のコミットなどのコードレビュー(たとえば同僚による)も非常に役立ちます。(テストスイートにバグを書かないのは難しいと思います...時々、テストを内部でテストする必要があります(健全性チェック):))。


0

開発者Aがバグのあるコードを書いたとしましょう。このコードは、意図したとおりに動作するわけではありませんが、少し異なるものです。開発者Bは、Aのコードが本来の仕様どおりに動作することに依存するコードを作成しましたが、Bのコードは機能しません。Bは調査し、Aのコード内の不正な動作を見つけて修正します。

一方、開発者Cのコードは、Aのコードの誤った動作に依存していたため、正常に機能するだけでした。Aのコードが正しくなりました。そして、Cのコードは機能しなくなります。つまり、コードを修正するときは、このコードを使用するユーザーと、修正されたコードによってその動作がどのように変化するかを非常に慎重に確認する必要があります。

別の状況がありました:いくつかのコードは誤動作し、ある状況Xで機能が完全に機能しなくなったので、その動作を変更して機能を動作させました。不幸な副作用は、機能全体が状況Xで重大な問題を抱え、至る所で失敗したことです。これは、状況が以前に発生したことがないため、誰にも完全に不明でした。まあ、それは難しいです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.