測試有關 if == int 的序列¶
有時候在程式中會有這樣的模式
if X == int_1:
pass
elif X == int_2:
pass
elif X == int_3:
pass
X
與許多合法的整數去做比較。當我們忘記測試合法數值外的值的時候,突變測試會產生存活的突變。
備註
statements 的順序不是這麼的重要
Reproducer¶
$ pip install nose
$ pip install https://github.com/sixty-north/cosmic-ray/zipball/master
$ cosmic-ray run --test-runner nose --baseline=10 example.json selinux.py -- tests.py:Test_mode_from_int
$ cosmic-ray report example.json
job ID 3:Outcome.SURVIVED:selinux
command: cosmic-ray worker selinux replace_Eq_with_GtE 2 nose -- -v tests.py:Test_mode_from_int
--- mutation diff ---
--- a/example_08/selinux.py
+++ b/example_08/selinux.py
@@ -7,7 +7,7 @@
retval += 'disabled'
elif (int_mode == modes.SELINUX_ENFORCING):
retval += 'enforcing'
- elif (int_mode == modes.SELINUX_PERMISSIVE):
+ elif (int_mode >= modes.SELINUX_PERMISSIVE):
retval += 'permissive'
return retval
job ID 16:Outcome.SURVIVED:selinux
command: cosmic-ray worker selinux replace_Eq_with_LtE 0 nose -- -v tests.py:Test_mode_from_int
--- mutation diff ---
--- a/example_08/selinux.py
+++ b/example_08/selinux.py
@@ -3,7 +3,7 @@
def mode_from_int(int_mode):
retval = ''
- if (int_mode == modes.SELINUX_DISABLED):
+ if (int_mode <= modes.SELINUX_DISABLED):
retval += 'disabled'
elif (int_mode == modes.SELINUX_ENFORCING):
retval += 'enforcing'
job ID 17:Outcome.SURVIVED:selinux
command: cosmic-ray worker selinux replace_Eq_with_LtE 1 nose -- -v tests.py:Test_mode_from_int
--- mutation diff ---
--- a/example_08/selinux.py
+++ b/example_08/selinux.py
@@ -5,7 +5,7 @@
retval = ''
if (int_mode == modes.SELINUX_DISABLED):
retval += 'disabled'
- elif (int_mode == modes.SELINUX_ENFORCING):
+ elif (int_mode <= modes.SELINUX_ENFORCING):
retval += 'enforcing'
elif (int_mode == modes.SELINUX_PERMISSIVE):
retval += 'permissive'
job ID 18:Outcome.SURVIVED:selinux
command: cosmic-ray worker selinux replace_Eq_with_LtE 2 nose -- -v tests.py:Test_mode_from_int
--- mutation diff ---
--- a/example_08/selinux.py
+++ b/example_08/selinux.py
@@ -7,7 +7,7 @@
retval += 'disabled'
elif (int_mode == modes.SELINUX_ENFORCING):
retval += 'enforcing'
- elif (int_mode == modes.SELINUX_PERMISSIVE):
+ elif (int_mode <= modes.SELINUX_PERMISSIVE):
retval += 'permissive'
return retval
total jobs: 24
complete: 24 (100.00%)
survival rate: 16.67%
殺死突變¶
要殺死所有的突變,我們需要測試合法範圍外的值:
$ cosmic-ray run --test-runner nose --baseline=10 example.json selinux.py -- tests.py:TestCompletely
$ cosmic-ray report example.json
程式碼¶
SELINUX_DISABLED = 0
SELINUX_ENFORCING = 1
SELINUX_PERMISSIVE = 2
import modes
def mode_from_int(int_mode):
retval = ""
if int_mode == modes.SELINUX_DISABLED:
retval += "disabled"
elif int_mode == modes.SELINUX_ENFORCING:
retval += "enforcing"
elif int_mode == modes.SELINUX_PERMISSIVE:
retval += "permissive"
# it doesn't matter if we have a trailing else clause or not
# uncomment this to experiment
# else:
# retval += "unknown"
return retval
import modes
import selinux
import unittest
class Test_mode_from_int(unittest.TestCase):
def test_with_disabled(self):
m = selinux.mode_from_int(modes.SELINUX_DISABLED)
self.assertEqual(m, "disabled")
def test_with_enforcing(self):
m = selinux.mode_from_int(modes.SELINUX_ENFORCING)
self.assertEqual(m, "enforcing")
def test_with_permissive(self):
m = selinux.mode_from_int(modes.SELINUX_PERMISSIVE)
self.assertEqual(m, "permissive")
class TestCompletely(Test_mode_from_int):
def test_with_values_outside_set(self):
for mode in [-1, 9999]:
m = selinux.mode_from_int(mode)
self.assertEqual(m, "")
if __name__ == "__main__":
unittest.main()