Literal value(xUnitTestPatterns読書会)

704 views

Published on

2011/3

Published in: Technology
  • Be the first to comment

Literal value(xUnitTestPatterns読書会)

  1. 1. Chapter  27.  Value  Pa0erns   Literal  Value xUnit  Test    Pa0erns  Reading  Group   2011/3/5   @goyoki
  2. 2. Literal  Value •  ハードコーティングした値の総称 –  Hard-­‐Coded  Value,  Constant  Value等 •  テストではパラメータを指定するためによく使 われる
  3. 3. How  It  Works •  例えば以下で多用される –  オブジェクトの属性の指定 –  SUTを呼び出すメソッドや、AsserMon  Methodの引 数の指定  •  期待値のLiteral  Valueは、手動やスプレッド シートで計算され、テストに転記によりHard-­‐ Codingされることがしばしばある
  4. 4. When  to  Use  It •  要求として特定値が指定されている場合 –  Literal  Valueは使われている値を明快にする –  要求からテストへの値の転記ミス、転記の手間削 減のため、データ駆動テストの導入が望ましい場 合がしばしばある
  5. 5. When  to  Use  It(注意点) •  Literal  Valueは値の関係性が見えにくくなる   –  Bad  Smell:Obsucure  Testsにつながる   –  値の意図が欠落する   –  例: •  意味的に同じ値を複数個所で直書き –  コードのコピペと同じ   –  意味的に同じであることが分からない •  本来関係ないパラメータだが同じ値を使った場合   –  意味的に値が同じかわかりにくい
  6. 6. When  to  Use  It(注意点) •  値の意味や関係性を明快にすべき –  Tests  as  DocumentaMon!   •  値の意味を明快に仕様   •  期待値とFixtureセットアップ値の関係を明快にしよう –  重要でない値も、例えばGenerated  Valuesで分か りやすくしよう
  7. 7. ImplementaMon  Notes •  コードの中で値をHard-­‐Codeするのが一般的 •  留意点   –  意味的に同じ値を複数箇所で使う場合 •  値の関係性が困難になる   •  Symbolic  Constantで代用する。 –  値の意図を表現したい場合 •  Self-­‐Describing  Valueを使う •  適切な名前のSymbolic  Constantを使う
  8. 8. Refactoring  Notes •  Literal  Valueは最初のリファクタリングとして取 り掛かりやすい public  void  testAddItemQuanMty_1()  throws  ExcepMon  {              Product  product  =  new  Product("Widget",  19.95);              Invoice  invoice  =  new  Invoice();              //  Exercise              invoice.addItemQuanMty(product,  1);              //  Verify              List  lineItems  =  invoice.getLineItems();              LineItem  actualItem  =  (LineItem)lineItems.get(0);              assertEquals(new  BigDecimal("19.95"),   actualItem.getExtendedPrice());   }
  9. 9. Symbolic  Constant(記号定数)の導入 •  Literal  Valueをシンボルに置き換える  •  同じLiteral  Valueを複数で使う場合に有効 •  機能的にはLiteral  Valueと全く等価だが、High  Test   Maintenance  Costのリスクを下げる。 public  void  testAddItemQuanMty_1s()  throws  ExcepMon  {              BigDecimal  widgetPrice  =  new  BigDecimal("19.95");              Product  product  =  new  Product("Widget",  widgetPrice);              Invoice  invoice  =  new  Invoice();              //  Exercise              invoice.addItemQuanMty(product,  1);              //  Verify              List  lineItems  =  invoice.getLineItems();              LineItem  actualItem  =  (LineItem)lineItems.get(0);              assertEquals(widgetPrice,  actualItem.getExtendedPrice());   } 19.95というLiteral  Valueの重複を置換
  10. 10. Self-­‐Describing  Valueの導入 •  値で、Literal  Valueの意味や意図を表現する –  「存在しない人名」という意図で文字列を使うなら、“Joe   Blow”などでなく、"Not  an  exisMng  customer"といった値に する。 public  void  testAddItemQuanMty_1b()  throws  ExcepMon  {              BigDecimal  widgetPrice  =  new  BigDecimal("19.95");                      Product  product  =  new  Product("Irrelevant  product  name",  widgetPrice);              Invoice  invoice  =  new  Invoice();              //  Exercise              invoice.addItemQuanMty(product,  1);              //  Verify              List  lineItems  =  invoice.getLineItems();              LineItem  actualItem  =  (LineItem)lineItems.get(0);              assertEquals(widgetPrice,  actualItem.getExtendedPrice());  } Irrelevant  product  name"と自ら意味を語らせる
  11. 11. DisMnct  Valueの導入 •  Self-­‐Describing  Valueの一種。 •  違う値を使うことで、意図として違うことを示す public  void  testAddItemQuanMty_1c()  throws  ExcepMon  {              BigDecimal  widgetPrice  =  new  BigDecimal("19.95");                      String  name  =  "Product  name";              String  sku  =  "Product  SKU";              Product  product  =  new  Product(name,  sku,  widgetPrice);              Invoice  invoice  =  new  Invoice();              //  Exercise              invoice.addItemQuanMty(product,  1);              //  Verify              List  lineItems  =  invoice.getLineItems();              LineItem  actualItem  =  (LineItem)lineItems.get(0);              assertEquals(name,  actualItem.getName());  }

×