Что вы думаете, когда логическое «если» имеет три результирующих пути кода? - PullRequest
2 голосов
/ 22 октября 2008

QA-тестер читал код 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
}

После пары смущающих попыток тестер понял, что они не могут вызвать строки оповещения, скрытые в третьем блоке.

Мне интересно узнать, является ли эта проблема более или менее специфичной для языка (могут ли не-JS люди учить уроки здесь?) И есть ли законные причины, по которым код закончился таким образом?

Как я могу найти / решить проблему?

Ответы [ 13 ]

8 голосов
/ 22 октября 2008

Хотя третий блок не может сработать в 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

Это напечатает 3, потому что NULL не равно или не равно любому другому значению.

4 голосов
/ 22 октября 2008

Это может произойти, если вы используете плохо сконструированные логические значения (обычно в ранних версиях C, когда не было истинного логического типа). Вы все еще можете найти это в Windows.

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

Ключевым моментом здесь является явное тестирование «ИСТИНА», которое предполагает, что существует только один-единственный способ, которым логическое значение может иметь истинное значение. При использовании целых чисел в качестве логических значений это не так.

В некоторых языках на некоторых компьютерах (Fortran на VMS) может быть много разных целочисленных значений, которые переходят в истину, а многие разные значения - в ложь. В Windows HRESULT при интерпретации как SUCCESS или FAILURE одинаков.

3 голосов
/ 22 октября 2008

Я видел случаи, когда в другом месте, если раньше было что-то еще (И / ИЛИ), и человек, который это исправил, просто «исправил» и не исследовал очень глубоко.

2 голосов
/ 22 октября 2008

Является ли эта проблема более или менее языком конкретные (могут ли не-JS люди учиться уроки здесь?)

Это проблема, не зависящая от языка. На Java довольно легко написать, например:

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

Главное, что нужно помнить, это то, что "if (! X)" не требуется. Делая это простым «остальным», мы получим более простой код.

Are there legitimate reasons code ended up this way?

В некотором роде. Это стандартная практика, когда условие else всегда существует, когда необходим провал. Проблема заключалась в том, что программист не думал, что он очень ясно: его «(form_field! = Empty)» было точно таким же, как простое «другое». Укажите это ему, и он должен ударить себя. Если нет, поставьте под сомнение его роль в команде.

Какие подходы следует использовать для найти / решить проблему (код покрытие, обзор кода, черный ящик тестирование и т. д.)

Инструменты статического анализа кода могут решить эту проблему. Тем не менее, я не знаю ни одного для Javascript. JSLint может поймать много плохих вещей, но не проблемы логического потока.

2 голосов
/ 22 октября 2008

статический анализ сказал бы вам, что третий случай - «мертвый код»

код, подобный этому, происходит из-за неправильного понимания булевой логики или из-за множественных изменений со временем разными людьми - или обоими; -)

это не относится к Javascript, такого рода ошибки могут быть допущены на любом языке, который имеет структуру if-else (или ее разумное факсимиле)

1 голос
/ 22 октября 2008

Возможно, не в JavaScript, но в любом языке, поддерживающем многопоточное программирование, и объявляют form_field таким образом, чтобы его можно было использовать более чем одному потоку.

Например, Алгоритм Петерсона содержит аналогично бесполезную двойную проверку:

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

Это защищает от состояния гонки. Было бы чертовски сложно создать тест, чтобы вызвать его.

Если нет возможных условий гонки, то это тот тип проверки, который мы в шутку называли «проверкой космических лучей», когда я заключил контракт на НАСА. : -)

1 голос
/ 22 октября 2008

Я знаю, что помню, как писал несколько таких же вещей еще на первом или втором курсе колледжа, прежде чем я знал что-то лучше. Но я не вижу причины сделать это сейчас.

Единственный способ, которым он даже близок к легитимному, - это если переменная «empty» или «form_field» является переменным, аналогично функции Now () в VB. Но в таком случае я бы так не написал. Вместо этого вы перехватываете значение один раз над блоком if и проверяете перехваченное значение.

1 голос
/ 22 октября 2008

Я не верю, что эта проблема вообще зависит от языка. Вы можете создавать похожие (некорректные) условные операторы на множестве других языков.

Кроме того, я не думаю, что есть законная причина для того, чтобы условное утверждение было структурировано таким образом. Как вы указали в комментарии, операторы в третьем блоке просто никогда не будут выполнены.

Вероятно, вы могли бы найти такие ошибки наиболее эффективно в обзоре кода. Однако, поскольку для этого требуется по крайней мере некоторое время, по крайней мере, от одного разработчика, вы можете лучше справляться с разработкой модульных тестов качества и проверкой покрытия кода. В этом случае вы, вероятно, заметили бы, что третья часть условного оператора никогда не использовалась.

0 голосов
/ 20 октября 2009

Это произошло в нашей компании, и я подумал, что самое смешное, что исполняется «мертвый код» во втором. В нашем случае это был нетипизированный указатель (не спрашивайте, почему у нас они есть), который был неправильно установлен и приведен к классу с логическим полем.

«if (A = TRUE) .. else if (A == FALSE) .. else ..» было применено к логическому полю. Полученный код asm был следующим:

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

очистить значение в al было> 1, и оно упало до else ..

тот факт, что кодер написал это, ожидая, что это произойдет, - другое дело ...

0 голосов
/ 22 октября 2008

Различные запахи появляются при разных измерениях.

Я нашел Cyclomatic Complexity инструменты полезными. Все со сложностью более 5 заслуживает более пристального внимания.

...