スキップしてメイン コンテンツに移動

投稿

ラベル(Automated Testing)が付いた投稿を表示しています

自動テスト: メリットとデメリット

自動テストのメリット 自動テストは「繰り返し」「誰でも」「手軽に」アプリケーションをテストできます。 この特徴によって、実際の開発プロセスでは、下記のメリットがあります。 1. 自分の予想していなかった部分が壊れていること(Regression)を検知できる 2. ケアレスミスを防げる 3. 他のエンジニアにも実装を頼みやすい システムに精通していないエンジニアに実装を頼んでも、適切な自動テストがあれば、ある程度の品質は保証できます。テストが失敗すれば、少なくとも使用からずれているといった問題は検知できます。さらに頼んだエンジニアのシステム設計理解も深まるという副次的なメリットも生まれます。自動テストが仕様書の代わりになるときもあります。 4. 自動テストが常に実行されているので、テスト対象のコードが動くという自信が持てる 5. コードの改善(リファクタリング)に取り組みやすくなる もちろん安全度100%ではないですが、なかったらとても安全に利ファクタリングはできません。特に入力と出力が明確でテストパターンが網羅されている場合、リファクタリングは非常に進めやすくなります。 自動テストのデメリット 自動テストは、このように品質のよいソフトウェアを開発する上で、非常に強力なツールです。しかし、大きな弱点も抱えています。筆者の経験をもとに列挙していきます。 1. テストコードの追加にコストがかかる テストコードの追加に際しても、テストデータの準備、設計、コーディングなどが必要になります。 2. 自動テストを構築するのにも技術力がいる テストコードを書くのも本番コードと同等(あるいはそれ以上)の技術力、設計力が要求されます。誰でも簡単にテストを追加可能な設計ができる、高速・安定したテストを組むことができるエンジニアが必要です。 3. テストコードの追加の優先度が下がりがちになる テストコードがなくてもアプリケーションは動いてしまうので、どうしても後回しになりがちです。どうしても本番のコード(テスト対象コード)の品質やバグFixが優先されてしまい、テストコード部分からカットされがちです。 4. チームでテストコードを書く文化がない 本番コードは、みんな頑張って書くのですが、テストコードはあまり書きたがらな...

自動テストが威力を発揮するビジネス環境

はじめに 今日は、自動テストが威力を発揮する、ビジネス環境について考察したいと思います。 今までの筆者の経験から、筆者が重要だと思う「自動テストが威力を発揮するビジネス環境因子」を3つあげます。 コードベースに触るチームメンバーの人数が多い メンバーの入れ替わりが激しい コード変更を短期的に繰り返す 逆に言うと上記の3つに当てはまらない環境の場合、自動テストの導入の効果は薄いです。 つまり コードベースに触るチームメンバーの人数が少ない メンバーがほとんど入れ替われない 一度リリースしたら、コード変更はバグがあったときのみ (一回発注・納品型スタイル) の場合、自動テスト導入しても、効果は薄いと思われます。 以下、重要だと思う因子3つの根拠を記します。 3つの因子の根拠 1. コードベースに触るチームメンバーの人数が多い 当たり前ですが、関わるメンバーが多ければ多いほど。誰がどこを直したかをメンバー間で共有することは難しくなり、コードの変更管理コストも上昇していきます。Aという変更と別メンバーのBという変更が合わさったことによって、システムに矛盾した振る舞いを引き起こさせる可能性もあります。 そういった状況でも、自動テストがあれば、少なくとも現状のロジックが破壊された場合には検知してくれるので、メンバーが多くても安心して開発を進めることができます。 もちろん、対象のコードが自動テストでカバーされている + 正しいビジネスロジックのテストで網羅されているということが前提条件になります。 2. メンバーの入れ替わりが激しい メンバーの入れ替わりが激しい場合、各メンバーが保有している知識が断片的で、システム全体の知識を持っている人が少ない、あるいは全くいないということが考えられます。またメンバーの入れ替わり画激しいため、知識は容易に失われてしまう可能性も高いです。 自動テストがあれば、自分の変更が、思いがけないところでロジックを破壊していても検知できますので、安心です。 ただし、その入れ替わっていくメンバーには、そのメンバーの責任でテストを追加してもらうことが必須になります。あまり移動しないコアメンバーがいるのであれば、そのコアメンバーがテストコードを書くほうが望ましいです。コア...

PHP Symfony 1.4 Action plus View Rendering PHPUnit Test

Symfony 1.4 Action plus View Rendering PHPUnit Test I wrote test case for executing action and rendering view test. However testing action plus final rendering result is quite not easy because you need to understand how Symfony 1.4 framework handles web request and rendering model to view internally. I have investigated in the framework a bit and found a solution. Please see the test case example in the next section. Code <?php $basePath = dirname(__FILE__).'/../../../../apps/your_app_name/modules/'; $modulePaths = glob($basePath.'*', GLOB_ONLYDIR); foreach($modulePaths as $modulePath) { require_once $modulePath.'/actions/actions.class.php'; } class ActionsTest extends PHPUnit_Framework_TestCase { public function testActions() { // create stub web request $request = $this->createStubfWebRequest(); // action you would like to test. // you should pass module and action name refelctively $actions = new TargetActions($this...

Google App Engine Java: Setup Test Configuration

If you want to test a class which depends on Google App Engine infrastructure, such as data storing functionality with "PersistenceManagerFactory", you should set up LocalServiceTestHelper before testing. I don't tell you the details very much, but I will show you the minimum test setup in the code below. This code was enough for me to test my data access object functionality. package com.dukesoftware.gaej.test; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig; import com.google.appengine.tools.development.testing.LocalServiceTestHelper; public class GoogleAppEngineTest { private static final LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig()); @BeforeClass public static void setUp() { helper.setUp(); } @AfterClass public static void tearDown() { he...

Automated Testing: Pairwise Testing, Mutation Testing, CI, TDD

I Introduced basic techniques for automated testing in the following posts. Unit Test by JUnit Parameterized Test Mock Test Theory Test In this post, I mention some hints for software testing. Pairwise Testing It is unrealistic to test all the combination of parameters because the number of the tests increase explosively. Pairwise Testing aims to redeuce the number of tests with enough test quality and coverage by providing effective and enough combination of test parameters. This MSDN: Pairwise Testing in the Real World: Practical Extensions to Test-Case Scenarios helps your understanding Pairwise Testing. The article also introduces the tool for Pairwise Testing. Mutation Testing Change the logic in the test target code (for example, change reverse an inequality sign in the "if" condition check), and check if the test result is changed (= the test case can detect the code change). Mutation Testing is "Test for test" - verifying the effectiveness of ...

Automated Testing: Theory Test

Theory test is relatively new feature in JUnit testing. In theory test, we define "theory" for parameter combination and filter them by "assume". Then only tests passed parameters by assume. Let's show you some example theory test code. In Junit test, we put @RunWith(Theories.class) annotation on test class for deining theory test. put @DataPoints for parameter data set. The code below shows how theory test works in JUnit. Actually this is not good example because there is no advantedges compared with parameterized test in this case. package com.dukesoftware.exchangerate.service; import junit.framework.Assert; import org.junit.After; import org.junit.BeforeClass; import org.junit.experimental.theories.DataPoints; import org.junit.experimental.theories.Theories; import org.junit.experimental.theories.Theory; import org.junit.runner.RunWith; import org.mockito.Mockito; import com.dukesoftware.exchangerate.api.ExchangeRateApi; import com.dukesoftware....

Automated Testing: Mock Test

Today's topic is Mock Test . In the previous posts, I introduced bunch of test cases but all of target class is class which hits actual service or production environment. However in the real world, in many cases we cannot simply use actual service class. Isolate from actual production service. ex. storing DB, calling external environment API. External API is too slow and we don't have to use acual data from the API but just would like to test clsasses which uses the API. Would like to controla data from API. Would like to test internal logic. You can use Mock Object, which we can control behaviour of class, for the above cases. There are a lot of Mock libraries (especially in Java). In this post, we use Mockito for explanation. You just downalod mockito-all-x.x.x.jar and include it to classpath, then you can use Mockito. Mockito Example Code I think you can easily understand how to use Mockito from the below code example. package com.dukesoftware.exchangerate.s...

Automated Testing: Parameterized Test

In the previous post , I introduced basic of Unit Testing. Next I introduce parameterized testing. Before explaning parameterized testing, let's define a simple service class which uses ExchangeRateApi calss. package com.dukesoftware.exchangerate.service; import java.util.HashMap; import java.util.Map; import com.dukesoftware.exchangerate.api.ExchangeRateApi; import com.dukesoftware.exchangerate.api.Rate; public class PriceCalculator { private final ExchangeRateApi api; private final Map<String, Rate> map = new HashMap<>(); private final static double FEE_RATE = 0.05; public PriceCalculator(ExchangeRateApi api) { this.api = api; } public void initialize() { } public void shutdown() { this.map.clear(); } public double calculatePrice(double price, String ccy1, String ccy2) { Rate rate = this.map.get(ccy1+":"+ccy2); if(rate == null) { // cac...

Automated Testing: Unit Test by JUnit

Unit testing From this post, I will explain basic of automated testing. In this post, I will show you very very basic of unit testing using JUnit. We use YahooExchangeRateApi as testing target code introduced in http://dukesoftware00.blogspot.com/2013/10/java-get-exchange-rate-from-yahoo.html . Unit Test class & Annotaions The first of first, write simple unit testing code for YahooExchangeRateApi class. A few things you should remenber: Add @Test annotation to test method. Use @BeforeClass for execute something *once* before actual all tests defined in the test class. Use @Before for execute something before actual *each* tests defined in the test class. Use @AfterClass and @After are simply opposite meaning of @BeforeClass and @Before. e.g. executed after test methods. You can test exception thrown by @Test(expected=Exception.class) Yeah that's all! Let's see the actual test class code.... package com.dukesoftware.exchangerate.api; import static junit.fra...

Selenium IDEの使い勝手について調査

Selenium IDEの概要 FireFoxのPlugin 公式ドキュメント 独断と偏見に満ちた長所・短所 長所 作成したテストを様々なプログラミング言語で出力可能 (File->Export Test Suite As...) ブラウザ上での操作をSelenium IDE Commandとして記録するマクロ機能あり 短所 正直、このpluginを導入するより、普通のSeleniumを使って、システムの実装言語だけでテストが完結している方が、プロジェクトの運用コストや学習コストが低くてすむ可能性大。 スクリプトを書いてみた感じだと'''面倒くさい'''。後々のテストのメンテナンスに難あり。 その他、メモ Html内の要素の選択方法 XPath, CSS, DOM, id属性, name属性などが使える Selenium CoreのLocatorsを参照 Assertion or Verification? Assert: テストに失敗すると、それ以降のテストコマンドは実行されない Verify: テストに失敗すると、結果はFailとして表示されるが、Verify以降のテストコマンドは引き続き実行される waitForコマンドは特定の要素が出現するまで待って、出現したら次のテストコマンドを実行する。Ajax系のテストに最適。