Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Java web application testing

5,958 views

Published on

JJUG CCC 2015 Spring

Published in: Software
  • Be the first to comment

Java web application testing

  1. 1. Java Web アプリケーショ ンのテスティングの話 JJUG CCC 2015 Spring tokuhirom
  2. 2. 初心者向けっちゃ 初心者向け
  3. 3. コミュニティイベントなので コミュニティからのフィード バック重視
  4. 4. 答えを提供するよりは 議論の元を提供する感じで
  5. 5. 自己紹介
  6. 6. 自己紹介なんて 不要だと思うかもしれません が。。
  7. 7. 業種の前提が無いと、 聞いても無意味
  8. 8. 自社サービスの ウェブアプリケーション の開発
  9. 9. 一昨年まで Perl 書い てたけど去年から Java
  10. 10. Native App 用の API サーバー等が主
  11. 11. Form Webapp multipart/form-data application/x-www-form-urlencoded HTML 従来手法
  12. 12. iPhone App Webapp Android App AngularJS App JSON JSON 近年のアプリ
  13. 13. 開発手法の話
  14. 14. Agile
  15. 15. それをAgileと呼ぶなら それはAgileなのだろう
  16. 16. 開発の手順 Server Spec Client QA
  17. 17. Iterative 1.2 1.1 2.0 2.1
  18. 18. 開発に利用している コンポーネント
  19. 19. Apache Tomcat MySQLJava8
  20. 20. 普通だ!
  21. 21. 自己紹介終わり。
  22. 22. 本編です
  23. 23. 質問は随時叫ぶなり手を あげるなりしてください。
  24. 24. 原則
  25. 25. 手動テスト最高です ね!!
  26. 26. (CENSORED)
  27. 27. ネイティブアプリ等は 機種ごとの差異なども あるので 最終的には必要
  28. 28. どこまで自動化するか
  29. 29. 手動でやるよりも 自動でやったほうが 楽になりそうだな~って ところまでやる。
  30. 30. ここ、テスト書いておかない と後で壊れそうだな というところを、「契約」とし て 書いておく
  31. 31. Web Application でのテ スト、どのレイヤでやるか。
  32. 32. どこまでスタブにする か
  33. 33. 近代的WebApp Browser Controller Model RDBMS 外部API
  34. 34. どこのレイヤでテスト する?
  35. 35. Model のテストを手厚 くやろう。
  36. 36. どうやる?
  37. 37. 悩みどころ
  38. 38. Q. RDBMSまわりの テスト、どうやるか?
  39. 39. A. RDBMSとのつきあ いかたによる
  40. 40. 深い付き合い 浅い付き合い
  41. 41. 1. RDBMS を絞り尽く したい派
  42. 42. SQLをゴリゴリ 書きたい
  43. 43. 2. JPA にすべてを委ね るよって人
  44. 44. JPAがRDBMSの差異 を吸収してくれる。。
  45. 45. はず
  46. 46. RDBMS に依存しない 実装を求める
  47. 47. H2 でテストするぞ!!!
  48. 48. 僕の場合
  49. 49. 1 です。
  50. 50. JPA は使わないので。。 (CENSORED)
  51. 51. SQL書きたいよ?
  52. 52. 一番テストしたいのは RDBMS とのつなぎ込み部分
  53. 53. RT : WEB+DB システムとは SQL と入出力仕様だ
  54. 54. というわけで、MySQLを利用 したテストの仕方をご紹介し ます。
  55. 55. よ~し、パパ MySQL を maven から 起動しちゃうぞ~
  56. 56. (CENSORED)
  57. 57. local に立ってる MySQL 使ってこ
  58. 58. CREATE DATABASE proj_test_deadbeef; プロジェクト名 ランダム生成文字列
  59. 59. スキーマのSQLを流し 込む!!!
  60. 60. for (SHOW TABLES) { DELETE FROM $_; } @Before
  61. 61. マスターデータを INSERTする
  62. 62. 自動生成したDBへの接続情報は DI かなにかでがんばって 設定しよう!!
  63. 63. DB のテストに関する 知見は以上になります。
  64. 64. 休憩
  65. 65. 外部APIのテスト
  66. 66. ところで、最近話題の microservices
  67. 67. SOA でもなんでもい いですが……
  68. 68. 僕の周りでは10年ぐらい前 疎結合ウェブアプリケーション と呼んでました。
  69. 69. コンポーネントを 細かい httpd に分けて HTTP で通信してこ↑
  70. 70. メリット: 分業しやすい 変更の影響範囲が明確
  71. 71. 弊社でも、 バズワードが出る前から 実践されております。 (CENSORED)
  72. 72. しかし、 テストがやや やりにくい。
  73. 73. どうするか?
  74. 74. クライアントライブラ リを DI で置き換える?
  75. 75. 速い。
  76. 76. テスト範囲が狭くなっ て良くない面がある。
  77. 77. 結合テストを別途行う ならいいけど。。
  78. 78. httpd を起動して モックサーバーを実行する
  79. 79. Embedded Jetty
  80. 80. servlettester-jetty github.com/tokuhirom/ servlettester-jetty
  81. 81. JettyServletTester.runServlet((req, resp) -> { resp.getWriter().print("Hey"); }, (uri) -> { try (CloseableHttpClient client = HttpClientBuilder.create() .build()) { HttpGet request = new HttpGet(uri); try (CloseableHttpResponse resp = client.execute(request)) { String body = EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8); assertEquals("Hey", body); } } });
  82. 82. http://localhost:12800/
  83. 83. httpd あげるの無駄な のでは????
  84. 84. 無駄だけど、jetty なら起 動速いし気にならない。
  85. 85. DB関連のほうが十分 に遅いので。。
  86. 86. 実際には、もっとシン プルに。。
  87. 87. apimock https://github.com/ tokuhirom/apimock
  88. 88. Sinatra風にサーバー側 実装を書ける
  89. 89. @Test public void test() { mockApi(mock -> { mock.get(“/api/member/detail“,c -> { return ImmutableMap.of(“hoge”, “fuga”); }); }, () -> { assertEquals(”fuga}”, injector.get(Client.class).getMember(1) .getHoge() ); } }
  90. 90. HTTPの通信を細かく 書けないと、 Regression Test 書きづらい。
  91. 91. 外部 API のテストに関する 知見は以上になります。
  92. 92. 休憩
  93. 93. コントローラのテスト
  94. 94. コントローラのテスト、 どうやるか
  95. 95. API サーバー のテスト
  96. 96. 極めて書きやすい。
  97. 97. httpd をあげて Apache HttpClient でアクセスする。
  98. 98. servlettester-jetty
  99. 99. JettyServletTester.runServlet( new MyServlet(), (uri) -> { // your test code } );
  100. 100. 実際のテストコードで は。。。
  101. 101. ControllerTestBase クラ ス的なので自動的にサー ブレット立ち上げる。
  102. 102. @Test public void test() { http.get(“/api/member/“) .isOK() .contentContains(“hogehoge”); }
  103. 103. JSON API だったらど うすんの?
  104. 104. @Test public void test() { val req = new Req(“hoge”, “fuga”); Res res = mech2.postJSON(“/api/ member/register“, req) .isOK() .parseJSON(Res.class); assertThat(res.getName()) .isEqualTo(“hoge”); }
  105. 105. @Test public void test() { http.post(“/api/member/create“) .param(“name”, “John”) .isOK() .contentContains(“hogehoge”); }
  106. 106. HTML のフォームとか ……?
  107. 107. あんま真面目にテスト してない。。
  108. 108. 人力のテストでカバー できるので。。
  109. 109. HTML 変わりまくるので、自動 化テストの手間が 見合わない。
  110. 110. コントローラのテスト の話は終わり。
  111. 111. ダミーデータの作成
  112. 112. public class TestBase { @Inject protected Creator create; }
  113. 113. @Test public void test() { Member member = create.member(); Blog blog = create.blog(member); // … }
  114. 114. fixture.yml 的なの メンテナンスが面倒
  115. 115. Web 屋さん、 Excel 嫌いな人もいるので。。
  116. 116. ダミーデータ作成の話、 終わり。
  117. 117. テストライブラリ どれがいいのか、という話
  118. 118. junit3 vs junit4
  119. 119. junit4 世代なので、素直 に junit4 つかってます
  120. 120. assertThat(actual, is(expected));
  121. 121. 読む分にはいいけど、 書きづらい。。
  122. 122. assertj を使う
  123. 123. assertThat(actual) .isEqualTo(expected)
  124. 124. 補完が効きやすい = IDE Friendly
  125. 125. assertThat(list) .hasSize(5)
  126. 126. 開発が活発
  127. 127. assertThat(uri) .hasPath(“/“) .hasPort(80);
  128. 128. 先週ぐらいに要望だし たら、だれか実装してた。
  129. 129. ところで、、
  130. 130. Google truth ってどう なの?
  131. 131. dagger2 とか、google 発 プロダクトで利用されてる
  132. 132. だいたい assertj と一緒
  133. 133. コードが小難しい assertj のほうが好き
  134. 134. まとめ • assertj 便利。
  135. 135. Continuous Integration
  136. 136. 全体の構成
  137. 137. gh:e jenkins エン ジニア Nexus Enterprise Deploy System ServerServer Server Server
  138. 138. Nexus Enterprise へは jenkins からしか上がらない
  139. 139. テスト通らないコード はリリースできない
  140. 140. CI は誰かがお膳立てして あげればみんな諦めて使う
  141. 141. Findbugs checkstyle
  142. 142. gh:e から p-r 投げたら テストが自動で回る
  143. 143. CI ないと、テストは ぶっ壊れる
  144. 144. CI 回さないと 自分の書いたコードを 誰かが壊す
  145. 145. CI は基本。
  146. 146. 僕のやり方まとめ • DB のテストは実際に DB を使う • 外部 API のテストは実際に API をコールする • コントローラのテストはサーブレットコンテナ を起動する • CI を常に回す
  147. 147. おしまい • (CENSORED)
  148. 148. 以上。

×