有效单元测试之可读性
生活随笔
收集整理的這篇文章主要介紹了
有效单元测试之可读性
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
斷言
斷言的基本原理和意圖隱藏在無意義的單詞和數字背后,難以理解,難以驗證斷言的正確性。
Bad eg.
@Test public void outputHasLineNumbers() {String content = "1st match on #1\nand\n2nd match on #3";String out = grep.grep("match", "test.txt", content);assertTrue(out.indexOf("test.txt:1 1st match") != -1);assertTrue(out.indexOf("test.txt:3 2nd match") != -1); }Good eg.
@Test public void outputHasLineNumbers() {String content = "1st match on #1\nand\n2nd match on #3";String out = grep.grep("match", "test.txt", content);assertThat(out, containsString("test.txt:1 1st match"));assertThat(out, containsString("test.txt:3 2nd match")); }?一個測試應該只有一個失敗的原因
按位
Bad eg.
@Test public void platformBitLength() {assertTrue(Platform.IS_32_BIT ^ Platform.IS_64_BIT); }Good eg.
@Test public void platformBitLength() {assertTrue("Not 32 or 64-bit platform?", Platform.IS_32_BIT || Platform.IS_64_BIT);assertFalse("Cant't be 32 and 64-bit at the same time." Platform.IS_32_BIT && Platform.IS_64_BIT); }附加細節
????????數據初始化+斷言細節--混在一起
Bad eg.
public class TestObjectSpace {private Ruby runtime;private ObjectSpace objectSpace;@Beforepublic void setUp() {runtime = Ruby.newInstance();objectSpace = new ObjectSpace();}@Testpublic void testObjectSpace() {IRubyObject o1 = runtime.newFixnum(10);IRubyObject o2 = runtime.newFixnum(20);IRubyObject o3 = runtime.newFixnum(30);IRubyObject o4 = runtime.newString("hello");objectSpace.add(o1);objectSpace.add(o2);objectSpace.add(o3);objectSpace.add(o4);List storedFixnums = new ArrayList(3);storedFixnums.add(o1);storedFixnums.add(o2);storedFixnums.add(o3);Iterator strings = objectSpace.iterator(runtime.getString());assertSame(o4, strings.text());assertNull(strings.next());Iterator numerics = objectSpace.iterator(runtime.getNumeric());for(int i=0; i<3; i++) {Object item = numerics.next();assertTrue(storedFixnums.contains(item));}assertNull(numerics.next());} }Good eg.
public class TestObjectSpace {private Ruby runtime;private ObjectSpace objectSpace;private IRubyObject string;private List<IRubyObject> fixnums;@Beforepublic void setUp() {runtime = Ruby.newInstance();objectSpace = new ObjectSpace();string = runtime.newString("hello");fixnums = new ArrayList<IRubyObject>() {{add(runtime.newFixnum(10));add(runtime.newFixnum(20));add(runtime.newFixnum(30));}};}@Testpublic void testObjectSpace() {//填充ObjectSpaceaddTo(space, string);addTo(space, fixnums)//檢查ObjectSpace的內容Iterator strings = space.iterator(runtime.getString());assertContainsExactly(strings, string);Iterator numerics = space.iterator(runtime.getNumeric());assertContainsExactly(numerics, fixnums);}private void addTo(ObjectSpace space, Object... values) {}private void addTo(ObjectSpace space, List values) {}private void assertContainsExactly(Iterator i, Object... values) {}private void assertContainsExactly(Iterator i, List values){} }方法粒度
????????人格分裂:一個測試方法內有多個測試。
Bad eg.
@Test public void testParsingCommandLineArguments() {String[] args = {"-f", "hello.txt", "-v", "--version"};Configuration config = new Configuration();config.processArguments(args);assertEquals("hello.txt", config.getFileName());assertFalse(config.isDebuggingEnabled());assertFalse(config.isWarningsEnabled());assertTrue(config.isVerbose());assertTrue(config.shouldShowVersion());config = new Configuration();try {config.processArguments(new String[] {"-f"});fail("Should've faild");} catch (InvalidArgumentException e) {// this is okay and expected} }Good eg.
public class TestConfiguration {private Configuration config;@Beforepublic void before() {config = new Configuration();}@Testpublic void validArgumentsProvided() {String[] args = {"-f", "hello.txt", "-v", "--version"};config.processArguments(args);assertEquals("hello.txt", config.getFileName());assertFalse(config.isDebuggingEnabled());assertFalse(config.isWarningsEnabled());assertTrue(config.isVerbose());assertTrue(config.shouldShowVersion());}@Test(expected = InvalidArgumentException.class)public void missingArgument() {config.processArguments(new String[] {"-f"});} }邏輯分割
????????過度分散,增加認知負擔。
Bad eg.
public class TestRuby {private Ruby runtime;@Beforepublic void before() {runtime = Ruby.newInstance();}@Testpublic void testVarAndMet() {runtime.getLoadService().init(new ArrayList());eval("load 'test/testVariableAndMethod.rb'");assertEquals("Hello World", eval("puts($a)"));assertEquals("dlroW olleH", eval("puts($b)"));assertEquals("Hello World", eval("puts $d.reverse, $c, $e.reverse"));assertEquals("135 20 3", eval("put $f, \" \", $g, \" \", $h"));} }代碼與文件分離testVariableAndMethod.rb a = String.new("Hello World"); b = a.reverse c = " " d = "Hello".reverse e = a[6, 5].reverse f = 100 + 35 g = 2 * 10 h = 13 % 5 $a = a $b = b $c = c $d = d $e = e $f = f $g = g $h = hGood eg.
public class TestRuby {private Ruby runtime;private AppendableFile script;@Beforepublic void before() {runtime = Ruby.newInstance();script = withTempFile();}@Testpublic void variableAssignment() {script.line("a = String.new('Hello')");script.line("b = 'World'");script.line("$c = 1 + 2");afterEvaluating(script);assertEquals("Hello", eval("puts(a)"));assertEquals("World", eval("puts b"));assertEquals("3", eval("puts $c"));}@Testpublic void methodInvocation() {script.line("a = 'Hello'.reverse");script.line("b = 'Hello'.length()");script.line("c = ' abc '.trim(' ', '_')");afterEvaluating(script);assertEquals("olleH", eval("puts a"));assertEquals("3", eval("puts b"));assertEquals("_abc_", eval("puts c"));}private void afterEvaluating(AppendableFile sourceFile) {eval("load '" + sourceFile.getAbsolutePath() + "'");} }魔法數字
Bad eg.
public class BowlingGameTest {@Testpublic void perfectGame() {roll(10, 12);assertThat(game.score(), is(equalTo(300)));}}Good eg.
public class BowlingGameTest {@Testpublic void perfectGame() {roll(pins(10), times(12));assertThat(game.score(), is(equalTo(300)));}private int pins(int n) {return n;}private int times(int n) {return n;} }冗長安裝
Bad eg.
public class PackageFetcherTest {private PackageFetcher fetcher;private Map downloads;private File tempDir;@Beforepublic void before() {String systemTempDir = System.getProperty("java.io.tmpdir");tempDir = new File(systemTempDir, "downloads");tempDir.mkDirs();String filename = "/manifest.xml";InputStream xml = getClass().getResourceAsStream(filename);Document manifest = XOM.parse(IO.streamAsString(xml));PresentationList presentations = new PresentationList();presentations.parse(manifest.getRootElement());PresentationStorage db = new PresentationStorage();List list = presentations.getResourcesMissingFrom(null, db);fetcher = new PackageFetcher();downloads = fetcher.extractDownloads(list);}@Afterpublic void after() {IO.delete(tempDir);}@Testpublic void downloadsAllResources() {fetcher.download(downloads, tempDir, new MockConnector());assertEquals(4, tempDir.list().length);} }Good eg.
public class PackageFetcherTest {private PackageFetcher fetcher;private Map downloads;private File tempDir;@Beforepublic void before() {fetcher = new PackageFetcher();tempDir = new File(systemTempDir, "downloads");downloads = extractMissingDownloadsFrom("/manifest.xml");}@Afterpublic void after() {IO.delete(tempDir);}@Testpublic void downloadsAllResources() {fetcher.download(downloads, tempDir, new MockConnector());assertEquals(4, tempDir.list().length);}private File createTempDir(String name) {String systemTempDir = System.getProperty("java.io.tmpdir");File dir = new File(systemTempDir, name);dir.mkDirs();return dir;}private Map extractMissingDownloadsFrom(String path) {PresentationStorage db = new PresentationStorage();List list = presentations.createPresentationListFrom(path);List downloads = list.getResourcesMissingFrom(null, db);return fetcher.extractDownloads(downloads);}private PresentationList createPresentationListFrom(String path) {PresentationList presentations = new PresentationList();presentations.parse(readManifestFrom(path).getRootElement());}private Document readManifestFrom(String path) {InputStream xml = getClass().getResourceAsStream(path);Document manifest = XOM.parse(IO.streamAsString(xml));} }過度保護
Bad eg.
@Test public void count() {Data data = project.getData();assertNotNull(data);//過度保護,沒必要assertEquals(4, data.count()); }Good eg.
@Test public void count() {Data data = project.getData();assertEquals(4, data.count()); }總結
以上是生活随笔為你收集整理的有效单元测试之可读性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Data JPA 从入门到
- 下一篇: android oreo 源码,andr