Citrus-Field TECH BLOG.

フリーランスのITエンジニア、iOSアプリの個人開発、業務委託(小売、ヘルスケア)を行っています。お仕事については、メールもしくはXのDMでご相談ください

テスト駆動開発で確実なロジックを設計、実装するための考え方

AndroidとiOSで、同一機能のネイティブアプリを開発する場合、AndroidとiOSのロジック(アーキテクチャのModel)は一致している必要があります。


アジャイル開発であっても、単体テストは、確実に漏れなく確認します。

正解はドキュメントでは無く、ロジックを確認できるテストコードです。


アーキテクチャがMVVMでもMVPでも、Android とiOSで共通のロジック(Model)が、実装されていなければ、同じ動作を担保できません。 
そのためには、Android側でJUnitを用いたテストコード、iOSでXCTestを用いたテストコード、詳細設計レベルのドキュメント、テスト仕様書をすることが必要です。


現在までにさまざまな開発支援ツールで、 - コードからドキュメントを生成するツール - ドキュメントからコードを生成するツール が、ありましたが、信頼できるものに出会うことは無かったです。それらのツールが生成したコードとドキュメントを人間が問題ないか確認する手間が負担となるためです。

この負担を減らしたくても、ツールの成果物が問題ないか確認する手間は、人間がテストコードを書くよりも信頼できるものはないです。 また、人間であれば、テストコードを書く時点で、仕様の抜け、漏れに気づくことが出来ます。 そして、テストができないコードを書いてしまうミスもなくせます。   ユニットテストは難しいものと考えないでください。   単純な、足し算を行うファンクションのテストコードの、例として、2+3を計算して、結果に5が戻り値になるか、サンプルコードを示します。   Swift、Kotlin、まだAndroidでJavaが使われているプロダクトがあるようなので、Javaのテストコードについても、サンプルコードを示します。  

Swiftで XCTestを使ったユニットテストのコード

 

1. ロジックのコード(Calculator.swift)

class Calculator {
    func add(_ a: Int, _ b: Int) -> Int {
        return a + b
    }
}


2. ユニットテストのコード(CalculatorTests.swift)

import XCTest

@testable import YourAppName
class CalculatorTests: XCTestCase {
    var calculator: Calculator!
    override func setUp() {
        super.setUp()
        calculator = Calculator()
    }

    override func tearDown() {
        calculator = nil
        super.tearDown()
    } 
 
    func testAddition() {
        let result = calculator.add(2, 3)
        XCTAssertEqual(result, 5, "Expected 2 + 3 to equal 5")
    }
}

ポイント

setUp でテスト対象オブジェクトを初期化し、tearDown でクリーンアップします。

XCTAssertEqual を使って、計算結果が期待通りであるかを検証します。

Android(Kotlinの場合)


Androidでは、JUnitとMockitoなどを使用してユニットテストを実行します。こちらも同じように、簡単な加算機能のユニットテストを見てみましょう。  


1. ロジックのコード(Calculator.kt)

class Calculator {
    fun add(a: Int, b: Int): Int {
        return a + b
    }
}


2. ユニットテストのコード(CalculatorTest.kt)


import org.junit.Assert.*
import org.junit.Before
import org.junit.Test

class CalculatorTest {
    private lateinit var calculator: Calculator

    @Before
    fun setUp() {
        calculator = Calculator()
    }

    @Test
    fun testAddition() {
        val result = calculator.add(2, 3)
        assertEquals(5, result)
    }
}

ポイント:

@Before アノテーションを使って、テスト前に必要なセットアップを行います。

assertEquals を使って、期待する結果と実際の結果を比較します。

Android(javaの場合)

1. ロジックのコード(Calculator.java)

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
}


2. ユニットテストのコード(CalculatorTest.java)

import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;

public class CalculatorTest {
    private Calculator calculator;
    @Before
    public void setUp() throws Exception {
        calculator = new Calculator();
    }

    @Test
    public void testAddition() {
        int result = calculator.add(2, 3);
        assertEquals(5, result);
    }
}

  ポイント:

@Before アノテーションで、各テストメソッドの実行前に setUp メソッドが呼ばれ、Calculator インスタンスを初期化します。

assertEquals を使用して、計算結果が期待通りであることを検証します。


Javaを使ったAndroidのユニットテストでは、JUnitを使い、Kotlinの時と同様にロジックの検証が可能です。

every one Happy Cording!