CleanCode第9章ユニットテスト
27811 ワード
エイズとTDDのおかげで、自動化ユニットテストのプログラマーが増え、ますます多くの傾向があります.
良好なテスト例を作成することは非常に重要です.
で失敗したユニットテストを記述する前に、実際のコードは記述されません. コンパイルは失敗せず、ユニットテストは失敗の程度でのみ記述されます. では、失敗したテストに合格するまで、実際のコードのみが作成されます. このようにコードを記述すると,開発とテストサイクルは約30秒に制限される.
->毎日数十個、毎月数百個、毎年数千個のテストケースがあります.
(実際のコードに相当する膨大なテストコードは管理上の問題を引き起こす.)
テストコードが不潔な場合は、次のことが起こります.
リリースの新しいバージョンごとに、チームのテストケースのメンテナンスとメンテナンスのコストが 増加します.の開発者の間では、テストコードが最大の不満となっています. の管理者が予測値が大きすぎる理由を尋ねると、チームはテストコードを非難します. テストキットを廃棄します. のテストコードがないため、開発者は修正後のコードが正しいかどうかを確認できません. 欠陥率が向上します. 予期せぬ欠陥数が増加すると、開発者は変更をためらうことになります. を変更すると、弊害が利益より大きいと判断され、コードは整理されません. コードが破壊されます. テストキットがなく、混在したコード、挫折した顧客とテストの努力が無駄になり、失望感だけが残った. ->テストケースは、開発の柔軟性、保守性、再利用性を提供するために簡単に変更できます.
きれいなテストコードを生成するために、
明確性、単純性、豊かな表現力が必要 addPageとassertSubStringを呼び出すために、重複するコードがたくさんあります. PathParserはネットワークロボットが使用する対象であり,テストに関係なく意図的にぼやけているだけである. 応答オブジェクトのコードと応答を収集し変換するコードが生成されなくても、関係ありません. がコードを理解するまで、テストケースを理解しませんでした. こちらはBUILD-OPERATE-CHECKモードに適しています
1.テスト資料を作成する.
2.操作テスト資料.
3.操作結果が正しいか確認する.
assert文が1の関数であるという結論は分かりやすく、迅速なコードですが、上記の例では「XMLとして出力」されたassert文と「特定の文字列を含む」assert文を1つにまとめています.
切り裂くと下と同じです.
このときTEMPLATE METHODを使うとより見やすくなります.
(与えられた/時間の部分を親に配置)
(サブクラスに一部を配置)
高速:テストが高速です. テストは速く回転します.
-テストが遅かったら
-頻繁に回らないと、最初から問題が見つからず、直らない.
-コードを整理することもできません.
-最終コード品質が低下し始めました. 独立:各テストは相互に依存できません. 1つのテストは、次のテストの実行環境に備えるべきではありません.
-各テストは独立して実行され、任意の順序で実行できます.
-テストが互いに依存している場合、1つの失敗が続くと、残りも失敗し続けるため、原因の診断が難しく、後続のテストで見つけなければならない欠陥が隠されています. 再現性:テストは任意の環境で再現できる必要があります. は、実環境、QA環境、バスで帰宅途中に使用するノートパソコン環境でも動作可能でなければならない.
-テストが実行できない環境がある場合は、テストが失敗した理由を説明する口実が発生します.
-環境がサポートされていないため、テストを実行できない場合があります. ワード検証:テストはBool値で結果を生成する必要があります.成功か失敗か. ユーザーにログファイルを読み込ませて、を通過したかどうかを判断することはできません.
-パスするかどうかを確認するために、2つのテキストファイルを手動で比較することはできません.
-テストが成功と失敗を自分で測らないと、判断が主観的になり、冗長な手作業で評価する必要があります. タイムリー:テストはタイムリーに記入しなければならない. ユニットテストは、テストする実際のコードを実装する前に実施される.
-実際のコードを実装した後にテストコードを作成すると、実際のコードはテストしにくいことがわかります.
-一部の実際のコードはテストが難しいと判定される可能性があります.
-実際のコードをテストできないように設計するかもしれません.
良好なテスト例を作成することは非常に重要です.
1.三つのTDD法則
->毎日数十個、毎月数百個、毎年数千個のテストケースがあります.
(実際のコードに相当する膨大なテストコードは管理上の問題を引き起こす.)
2.清潔なテストコードを保持する
テストコードが不潔な場合は、次のことが起こります.
リリース
3.クリーンなテストコード
きれいなテストコードを生成するために、
明確性、単純性、豊かな表現力が必要
public void testGetPageHieratchyAsXml() throws Exception {
crawler.addPage(root, PathParser.parse("PageOne"));
crawler.addPage(root, PathParser.parse("PageOne.ChildOne"));
crawler.addPage(root, PathParser.parse("PageTwo"));
request.setResource("root");
request.addInput("type", "pages");
Responder responder = new SerializedPageResponder();
SimpleResponse response =
(SimpleResponse) responder.makeResponse(new FitNesseContext(root), request);
String xml = response.getContent();
assertEquals("text/xml", response.getContentType());
assertSubString("<name>PageOne</name>", xml);
assertSubString("<name>PageTwo</name>", xml);
assertSubString("<name>ChildOne</name>", xml);
}
public void testGetPageHieratchyAsXmlDoesntContainSymbolicLinks() throws Exception {
WikiPage pageOne = crawler.addPage(root, PathParser.parse("PageOne"));
crawler.addPage(root, PathParser.parse("PageOne.ChildOne"));
crawler.addPage(root, PathParser.parse("PageTwo"));
PageData data = pageOne.getData();
WikiPageProperties properties = data.getProperties();
WikiPageProperty symLinks = properties.set(SymbolicPage.PROPERTY_NAME);
symLinks.set("SymPage", "PageTwo");
pageOne.commit(data);
request.setResource("root");
request.addInput("type", "pages");
Responder responder = new SerializedPageResponder();
SimpleResponse response =
(SimpleResponse) responder.makeResponse(new FitNesseContext(root), request);
String xml = response.getContent();
assertEquals("text/xml", response.getContentType());
assertSubString("<name>PageOne</name>", xml);
assertSubString("<name>PageTwo</name>", xml);
assertSubString("<name>ChildOne</name>", xml);
assertNotSubString("SymPage", xml);
}
public void testGetDataAsHtml() throws Exception {
crawler.addPage(root, PathParser.parse("TestPageOne"), "test page");
request.setResource("TestPageOne"); request.addInput("type", "data");
Responder responder = new SerializedPageResponder();
SimpleResponse response =
(SimpleResponse) responder.makeResponse(new FitNesseContext(root), request);
String xml = response.getContent();
assertEquals("text/xml", response.getContentType());
assertSubString("test page", xml);
assertSubString("<Test", xml);
}
これは悪いテストコードです.1.テスト資料を作成する.
2.操作テスト資料.
3.操作結果が正しいか確認する.
public void testGetPageHierarchyAsXml() throws Exception {
makePages("PageOne", "PageOne.ChildOne", "PageTwo");
submitRequest("root", "type:pages");
assertResponseIsXML();
assertResponseContains(
"<name>PageOne</name>", "<name>PageTwo</name>", "<name>ChildOne</name>");
}
public void testSymbolicLinksAreNotInXmlPageHierarchy() throws Exception {
WikiPage page = makePage("PageOne");
makePages("PageOne.ChildOne", "PageTwo");
addLinkTo(page, "PageTwo", "SymPage");
submitRequest("root", "type:pages");
assertResponseIsXML();
assertResponseContains(
"<name>PageOne</name>", "<name>PageTwo</name>", "<name>ChildOne</name>");
assertResponseDoesNotContain("SymPage");
}
public void testGetDataAsXml() throws Exception {
makePageWithContent("TestPageOne", "test page");
submitRequest("TestPageOne", "type:data");
assertResponseIsXML();
assertResponseContains("test page", "<Test");
}
4.テストごとにassertを1つずつ
assert文が1の関数であるという結論は分かりやすく、迅速なコードですが、上記の例では「XMLとして出力」されたassert文と「特定の文字列を含む」assert文を1つにまとめています.
切り裂くと下と同じです.
public void testGetPageHierarchyAsXml() throws Exception {
givenPages("PageOne", "PageOne.ChildOne", "PageTwo");
whenRequestIsIssued("root", "type:pages");
thenResponseShouldBeXML();
}
public void testGetPageHierarchyHasRightTags() throws Exception {
givenPages("PageOne", "PageOne.ChildOne", "PageTwo");
whenRequestIsIssued("root", "type:pages");
thenResponseShouldContain(
"<name>PageOne</name>", "<name>PageTwo</name>", "<name>ChildOne</name>"
);
}
このように分離すると、重複するコードがたくさんあります.このときTEMPLATE METHODを使うとより見やすくなります.
(与えられた/時間の部分を親に配置)
(サブクラスに一部を配置)
5.F.I.R.S.T—5つのクリーンなテストルール
-テストが遅かったら
-頻繁に回らないと、最初から問題が見つからず、直らない.
-コードを整理することもできません.
-最終コード品質が低下し始めました.
-各テストは独立して実行され、任意の順序で実行できます.
-テストが互いに依存している場合、1つの失敗が続くと、残りも失敗し続けるため、原因の診断が難しく、後続のテストで見つけなければならない欠陥が隠されています.
-テストが実行できない環境がある場合は、テストが失敗した理由を説明する口実が発生します.
-環境がサポートされていないため、テストを実行できない場合があります.
-パスするかどうかを確認するために、2つのテキストファイルを手動で比較することはできません.
-テストが成功と失敗を自分で測らないと、判断が主観的になり、冗長な手作業で評価する必要があります.
-実際のコードを実装した後にテストコードを作成すると、実際のコードはテストしにくいことがわかります.
-一部の実際のコードはテストが難しいと判定される可能性があります.
-実際のコードをテストできないように設計するかもしれません.
Reference
この問題について(CleanCode第9章ユニットテスト), 我々は、より多くの情報をここで見つけました https://velog.io/@miiunii/CleanCode-9장-단위테스트テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol