2

QA テスターは、Web フォームの機能テストを作成するために HTML/JS コードを読んでいて、次のことを確認しました。

if (form_field == empty)
{
...do stuff for empty field
}
else if (form_field != empty)
{
...do stuff for non-empty field
}
else
{
...do stuff that will never be done
}

恥ずかしい試みを数回行った後、テスターは、3 番目のブロックに隠されているアラート文字列をトリガーできないことに気付きました。

私が疑問に思っているのは、この問題が多かれ少なかれ言語固有のものであるかどうか (非 JS の人々はここでレッスンを学ぶことができますか?)、コードがこのようになった正当な理由はありますか?

問題を見つけて対処するにはどうすればよいですか?

4

13 に答える 13

8

3 番目のブロックは Javascript でトリガーできませんが、すべての言語でそうではありません。T-SQL の場合:

declare @test as int

set @test = null

if @test = 1 
  print 1
else if not @test = 1
  print 2
else 
  print 3

NULL は他の値と等しくなく、等しくないため、これは 3 を出力します。

于 2008-10-22T17:13:30.233 に答える
4

これは、不適切に設計されたブール値を使用した場合に発生する可能性があります (真のブール型がなかった初期の C では一般的でした)。このようなものは、まだ Windows で見つけることができます。

BOOL result = SomeWindowsAPI();
if (result == TRUE)
{
    // success
}
else if (result == FALSE)
{
    // failure
}
else
{
    // wtf?
}

ここで重要なのは、ブール値が真の値を持つことができる唯一の方法があると仮定する「TRUE」の明示的なテストです。ブール値として整数を使用する場合、これは当てはまりません。

一部のコンピューター (VMS 上の Fortran) の一部の言語では、true に解決される多くの異なる整数値と、false に解決される多くの異なる値が存在する可能性があります。Windows では、HRESULT が SUCCESS または FAILURE として解釈される場合も同様です。

于 2008-10-22T17:27:13.683 に答える
3

else if が何か他のもの (AND/OR) を持っていて、それを修正した人が「修正」しただけで、あまり深く調査しなかったケースを見てきました。

于 2008-10-22T17:10:27.117 に答える
2

静的解析では、3 番目のケースは「デッド コード」であることがわかります。

このようなコードは、ブール論理の誤解、またはさまざまな人々による時間の経過に伴う複数の編集、またはその両方に由来します;-)

これは Javascript に固有のものではありません。この種の間違いは、if-else 構造 (またはその合理的な複製) を持つ任意の言語で発生する可能性があります。

于 2008-10-22T17:11:49.690 に答える
2

この問題は多かれ少なかれ言語固有のものですか (非 JS の人々はここで教訓を学ぶことができますか?)

これは言語に依存しない問題です。たとえば、Java で次のように記述するのは非常に簡単です。

if(x)
{
  //do something
}
else if(!x)
{
  //do something else
}
else
{
  //never, ever, do anything
}

覚えておくべき重要なことは、「if(!x)」は必要ないということです。単純な「else」を作成すると、より単純なコードが作成されます。

Are there legitimate reasons code ended up this way?

並べ替え。フォールスルーが必要な場合、else 条件が常に存在するのが標準的な方法です。問題は、プログラマーが単一の "(form_field != empty)" が単純な "else" とまったく同じであると明確に考えていなかったことです。彼にそれを指摘し、彼は自分自身を蹴る必要があります. そうでない場合は、チームでの彼の役割に疑問を投げかけます。

問題を見つけて対処するためにどのようなアプローチを使用する必要があるか (コード カバレッジ、コード レビュー、ブラックボックス テストなど)

静的コード分析ツールは、この種の問題をキャッチできます。ただし、Javascriptについては知りません。JSLintは多くの悪いものをキャッチできますが、ロジック フローの問題はキャッチできません。

于 2008-10-22T17:16:50.863 に答える
1

この問題が言語固有のものであるとはまったく思いません。同様の (欠陥のある) 条件文をさまざまな他の言語で作成できます。

また、条件文をこのように構成する正当な理由があるとは思いません。コメントで述べているように、3 番目のブロックのステートメントは決して実行されません。

このような間違いは、コード レビューで最も効果的に見つけることができるでしょう。ただし、これには少なくとも 1 人の開発者がかなりの時間を費やす必要があるため、品質の高い単体テストを開発し、コード カバレッジを検査する方がよい場合があります。この場合、条件ステートメントの 3 番目の部分が使用されていないことに気付いたでしょう。

于 2008-10-22T17:10:20.690 に答える
1

大学の最初の1年か2年に、よくわからないうちに、そのような方法でいくつか書いたことを覚えています。でも今はそうする理由が見当たらない。

正当に近い唯一の方法は、VB の Now() 関数と同様に、「空」または「form_field」のいずれかが揮発性の値であった場合です。しかし、その場合、私はこのように書きません。代わりに、if ブロックの上で一度値をトラップし、トラップされた値をテストします。

于 2008-10-22T17:11:43.667 に答える
1

おそらく JavaScript にはありませんが、マルチスレッド プログラミングをサポートし、複数のスレッド間で共有されるように form_fieldを宣言する言語であれば、実際にそのようなことが起こる可能性があります。

たとえば、Peterson のアルゴリズムには、同様に役に立たないように見える二重チェックが含まれています。

     turn = 1;
     while( flag[1] && turn == 1 );

ただし、それは競合状態から保護しています。それを引き起こすためのテストを生成することは、依然として非常に困難です。

競合状態の可能性がない場合、これは、私が NASA と契約したときに冗談めかして「宇宙線チェック」と呼んだ種類のチェックです。:-)

于 2008-10-22T17:34:53.480 に答える
0

さまざまな匂いがさまざまな測定値で現れます。

循環的複雑度ツールが便利だと思いました。複雑さが約5を超えるものはすべて、詳しく調べる価値があります。

于 2008-10-22T17:39:14.237 に答える
0

一般形では

if (a)
  //1
else if (!a)
  //2
else
  //3

に常に減らすことができます

if (a)
  //1
else
  //2

副作用なし。

于 2008-10-22T17:10:47.977 に答える
0

これはうちの会社でも起きたのですが、2番目の「デッドコード」が実行されているのが一番面白いと思いました。私たちの場合、それは型指定されていないポインターであり (理由は聞かないでください)、誤って設定され、ブール型フィールドを持つクラスにキャストされました。

" if (A = TRUE) .. else if (A == FALSE) .. else .." がブール フィールドに適用されました。結果の asm コードは次のとおりです。

cmp al,$01
jnz +$0c
...
test al,al
jnz +$0c
...

alの値が > 1 であり、elseに失敗したことをクリアします。

コーダーがそれが起こることを期待してこれを書いたという事実は別の問題です...

于 2009-10-20T09:59:55.063 に答える
0
  • この問題は多かれ少なかれ言語固有のものですか (非 JS の人々はここで教訓を学ぶことができますか?)

いいえ。ブランチと比較を使用すると、どの言語でもこの種のコードに遭遇する可能性があります。

  • コードがこのようになった正当な理由はありますか?
  • 問題を見つけて対処するためにどのようなアプローチを使用する必要があるか (コード カバレッジ、コード レビュー、ブラックボックス テストなど)

いいえ、そうではありません。そのコードは、ブール比較以外のものから始まったと思います。空、数値、非数値、または空、1 ~ 5 文字、または 5 文字以上などの可能性があります。ロジックが空または非空に変更された場合、3 番目のブロックは削除されているはずです。これは通常、ピア レビューなどで検出されます。

言語によっては、一部のコンパイラがこれをキャッチすることさえあります。レビューはそれをキャッチします。ブラック ボックス テストはコードをチェックしないため、チェックしませんが、ホワイト ボックス テストはチェックします (ただし、実際にテストが行​​われる前に、コードを確認するとすぐに気付くはずです)。

于 2008-10-22T17:15:00.447 に答える
0

単一の条件 A をテストしている場合、このクラスの問題は簡単に見つけることができます。

また、条件 A と B があれば、それほど難しいことではありません。A、not-A と B、not-A と not-B を探します (たとえば)。すべてをカバーしたことはかなり簡単にわかります。ケース。

場合によっては、何らかの理由で条件がリファクタリングされ、(上記の不自然な例を使用して) 3 つのブロックと結果の WTF が残されることがあります。

しかし、条件 A、B、C、D があるとしたらどうでしょうか。スタックされた if-else は、実際には危険な方法ですが、時にはそれが行われる方法です。

完全な真理値表を作成することで、ロジック カバレッジの「穴」を簡単に見つけることができます。これを行う良い方法は、カルノー マップを使用することです。Karnaugh マップに関するウィキペディアのエントリは、出発点として最適です (写真付きでも!)。ソフトウェア コーディングの場合、(少なくとも、通常は) 重複することなくマップを完全にカバーする必要があります。

于 2008-10-22T17:23:34.050 に答える