測試 if == string 序列¶
有時候程式中會有這樣的模式
if X == "string_1":
pass
elif X == "string_2":
pass
elif X == "string_3":
pass
X
與許多合法的字串去做比較。當我們忘記測試合法字串外的值的時候,突變測試會產生存活的突變。
備註
順序並不是這麼的重要
Reproducer¶
$ pip install nose
$ pip install https://github.com/sixty-north/cosmic-ray/zipball/master
$ celery -A cosmic_ray.tasks.worker worker
$ cosmic-ray run --test-runner nose --baseline=10 example.json selinux_str.py -- tests_str.py:Test_mode_from_str
$ cosmic-ray report example.json
job ID 4:Outcome.SURVIVED:selinux_str
command: cosmic-ray worker selinux_str mutate_comparison_operator 2 nose -- tests_str.py:Test_mode_from_str
--- mutation diff ---
--- a/example_08/selinux_str.py
+++ b/example_08/selinux_str.py
@@ -3,7 +3,7 @@
def mode_from_str(str_mode):
retval = None
- if (str_mode == 'disabled'):
+ if (str_mode <= 'disabled'):
retval = modes.SELINUX_DISABLED
elif (str_mode == 'enforcing'):
retval = modes.SELINUX_ENFORCING
job ID 8:Outcome.SURVIVED:selinux_str
command: cosmic-ray worker selinux_str mutate_comparison_operator 6 nose -- tests_str.py:Test_mode_from_str
--- mutation diff ---
--- a/example_08/selinux_str.py
+++ b/example_08/selinux_str.py
@@ -3,7 +3,7 @@
def mode_from_str(str_mode):
retval = None
- if (str_mode == 'disabled'):
+ if (str_mode in 'disabled'):
retval = modes.SELINUX_DISABLED
elif (str_mode == 'enforcing'):
retval = modes.SELINUX_ENFORCING
job ID 12:Outcome.SURVIVED:selinux_str
command: cosmic-ray worker selinux_str mutate_comparison_operator 10 nose -- tests_str.py:Test_mode_from_str
--- mutation diff ---
--- a/example_08/selinux_str.py
+++ b/example_08/selinux_str.py
@@ -5,7 +5,7 @@
retval = None
if (str_mode == 'disabled'):
retval = modes.SELINUX_DISABLED
- elif (str_mode == 'enforcing'):
+ elif (str_mode <= 'enforcing'):
retval = modes.SELINUX_ENFORCING
elif (str_mode == 'permissive'):
retval = modes.SELINUX_PERMISSIVE
job ID 16:Outcome.SURVIVED:selinux_str
command: cosmic-ray worker selinux_str mutate_comparison_operator 14 nose -- tests_str.py:Test_mode_from_str
--- mutation diff ---
--- a/example_08/selinux_str.py
+++ b/example_08/selinux_str.py
@@ -5,7 +5,7 @@
retval = None
if (str_mode == 'disabled'):
retval = modes.SELINUX_DISABLED
- elif (str_mode == 'enforcing'):
+ elif (str_mode in 'enforcing'):
retval = modes.SELINUX_ENFORCING
elif (str_mode == 'permissive'):
retval = modes.SELINUX_PERMISSIVE
job ID 20:Outcome.SURVIVED:selinux_str
command: cosmic-ray worker selinux_str mutate_comparison_operator 18 nose -- tests_str.py:Test_mode_from_str
--- mutation diff ---
--- a/example_08/selinux_str.py
+++ b/example_08/selinux_str.py
@@ -7,7 +7,7 @@
retval = modes.SELINUX_DISABLED
elif (str_mode == 'enforcing'):
retval = modes.SELINUX_ENFORCING
- elif (str_mode == 'permissive'):
+ elif (str_mode <= 'permissive'):
retval = modes.SELINUX_PERMISSIVE
return retval
job ID 22:Outcome.SURVIVED:selinux_str
command: cosmic-ray worker selinux_str mutate_comparison_operator 20 nose -- tests_str.py:Test_mode_from_str
--- mutation diff ---
--- a/example_08/selinux_str.py
+++ b/example_08/selinux_str.py
@@ -7,7 +7,7 @@
retval = modes.SELINUX_DISABLED
elif (str_mode == 'enforcing'):
retval = modes.SELINUX_ENFORCING
- elif (str_mode == 'permissive'):
+ elif (str_mode >= 'permissive'):
retval = modes.SELINUX_PERMISSIVE
return retval
job ID 24:Outcome.SURVIVED:selinux_str
command: cosmic-ray worker selinux_str mutate_comparison_operator 22 nose -- tests_str.py:Test_mode_from_str
--- mutation diff ---
--- a/example_08/selinux_str.py
+++ b/example_08/selinux_str.py
@@ -7,7 +7,7 @@
retval = modes.SELINUX_DISABLED
elif (str_mode == 'enforcing'):
retval = modes.SELINUX_ENFORCING
- elif (str_mode == 'permissive'):
+ elif (str_mode in 'permissive'):
retval = modes.SELINUX_PERMISSIVE
return retval
total jobs: 25
complete: 25 (100.00%)
survival rate: 28.00%
殺死突變¶
要殺死突變我們需要測試合法數值外的值:
$ cosmic-ray run --test-runner nose --baseline=10 example.json selinux_str.py -- tests_str.py:TestCompletely
$ cosmic-ray report example.json
剩餘突變¶
當在測試字串比較時 ==/in 兩個突變是相等的且不能被殺死
- elif (str_mode == 'permissive'):
+ elif (str_mode in 'permissive'):
程式碼¶
SELINUX_DISABLED = 0
SELINUX_ENFORCING = 1
SELINUX_PERMISSIVE = 2
import modes
def mode_from_str(str_mode):
retval = None
if str_mode == "disabled":
retval = modes.SELINUX_DISABLED
elif str_mode == "enforcing":
retval = modes.SELINUX_ENFORCING
elif str_mode == "permissive":
retval = modes.SELINUX_PERMISSIVE
return retval
import modes
import selinux_str
import unittest
class Test_mode_from_str(unittest.TestCase):
def test_with_disabled(self):
m = selinux_str.mode_from_str("disabled")
self.assertEqual(m, modes.SELINUX_DISABLED)
def test_with_enforcing(self):
m = selinux_str.mode_from_str("enforcing")
self.assertEqual(m, modes.SELINUX_ENFORCING)
def test_with_permissive(self):
m = selinux_str.mode_from_str("permissive")
self.assertEqual(m, modes.SELINUX_PERMISSIVE)
class TestCompletely(Test_mode_from_str):
def test_with_values_outside_set(self):
for mode in ['aaaaa', 'zzzzz']:
m = selinux_str.mode_from_str(mode)
self.assertEqual(m, None)
if __name__ == "__main__":
unittest.main()