JUnitを使ってみた(2)出力結果が多岐になるプログラム

カテゴリ: ブログ一覧学習・研修

前回に引き続きましてJUnitの使い方を模索します。

前回の記事はこちらになります。
JUnitを使ってみた
前回の記事は画像が多く見づらいため修正する予定です。

今回は、BMIを計測するプログラムを題材にJUnitについて考えてみます。
今のところ結論は次回に持ち越す予定ですが、
追記という形でこの記事に考察結果を書くかもしれません。

さて、メインのプログラムは以下になります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package arraytestsample;
 
import java.math.BigDecimal;
 
public class BMI {
 
    private BigDecimal value;
 
    public BMI(int height, int weight) {
 
        BigDecimal workHeight = new BigDecimal(height);
        workHeight = workHeight.divide(new BigDecimal(100));
        workHeight = workHeight.multiply(workHeight);
 
        BigDecimal workWeight = new BigDecimal(weight);
        BigDecimal workBMI = workWeight.divide(workHeight, 2, BigDecimal.ROUND_HALF_UP);
 
        value = workBMI.setScale(1, BigDecimal.ROUND_HALF_UP);
    }
 
    public String getValue() {
        return value.toString();
    }
 
    public String getComment() {
        if (value.doubleValue() > 24) {
            return "肥満の可能性があります";
        } else if (value.doubleValue() < 18.5) {
            return "痩せている可能性があります";
        } else {
            return "標準的と思われます";
        }
    }
}
package arraytestsample;

import java.math.BigDecimal;

public class BMI {

    private BigDecimal value;

    public BMI(int height, int weight) {

        BigDecimal workHeight = new BigDecimal(height);
        workHeight = workHeight.divide(new BigDecimal(100));
        workHeight = workHeight.multiply(workHeight);

        BigDecimal workWeight = new BigDecimal(weight);
        BigDecimal workBMI = workWeight.divide(workHeight, 2, BigDecimal.ROUND_HALF_UP);

        value = workBMI.setScale(1, BigDecimal.ROUND_HALF_UP);
    }

    public String getValue() {
        return value.toString();
    }

    public String getComment() {
        if (value.doubleValue() > 24) {
            return "肥満の可能性があります";
        } else if (value.doubleValue() < 18.5) {
            return "痩せている可能性があります";
        } else {
            return "標準的と思われます";
        }
    }
}

BMIの数値の他、肥満に当たる数値なのか、
痩せている傾向にある数値なのか、それ以外の標準的な範囲なのかを日本語で出力できます。

身長と体重を入力してしまえば結果は確定するため、
コンストラクタで身長と体重を受け取る形にしました。

main関数から呼んでみます。

1
2
3
4
5
6
7
8
9
package arraytestsample;
 
public class ArrayTestSample {
    public static void main(String[] args) {
        BMI bmi = new BMI(160, 50);
        System.out.println("BMIの値は:" + bmi.getValue());
        System.out.println("BMI値による傾向は:" + bmi.getComment());
    }    
}
package arraytestsample;

public class ArrayTestSample {
    public static void main(String[] args) {
        BMI bmi = new BMI(160, 50);
        System.out.println("BMIの値は:" + bmi.getValue());
        System.out.println("BMI値による傾向は:" + bmi.getComment());
    }    
}

実行結果:

BMIの値は:19.5
BMI値による傾向は:標準的と思われます

問題なく実行できたようです。

では、肥満傾向、痩せ傾向、標準のそれぞれをテストするJUnitコードを書いてみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package arraytestsample;
 
import org.junit.Test;
import static org.junit.Assert.*;
 
public class BMITest {
 
    public BMITest() {
    }
 
    @Test
    public void testFat() {
        BMI bmi = new BMI(160, 62);
        assertEquals("24.2", bmi.getValue());
        assertEquals("肥満の可能性があります", bmi.getComment());
    }
 
    @Test
    public void testSlim() {
        BMI bmi = new BMI(160, 47);
        assertEquals("18.4", bmi.getValue());
        assertEquals("痩せている可能性があります", bmi.getComment());
    }
 
    @Test
    public void testNormal() {
        BMI bmi = new BMI(160, 55);
        assertEquals("21.5", bmi.getValue());
        assertEquals("標準的と思われます", bmi.getComment());
    }
}
package arraytestsample;

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

public class BMITest {

    public BMITest() {
    }

    @Test
    public void testFat() {
        BMI bmi = new BMI(160, 62);
        assertEquals("24.2", bmi.getValue());
        assertEquals("肥満の可能性があります", bmi.getComment());
    }

    @Test
    public void testSlim() {
        BMI bmi = new BMI(160, 47);
        assertEquals("18.4", bmi.getValue());
        assertEquals("痩せている可能性があります", bmi.getComment());
    }

    @Test
    public void testNormal() {
        BMI bmi = new BMI(160, 55);
        assertEquals("21.5", bmi.getValue());
        assertEquals("標準的と思われます", bmi.getComment());
    }
}

テストの実行結果:

Testsuite: arraytestsample.BMITest
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.36 sec

正常にテストが実行できました。
BMI値は一律な計算による結果です。どんな入力がされても結果は同一の式によりはじき出されます。
それに対し getCommnet() で得られるコメントは理解しやすいように日本語で表現されてものです。
入力値によって得られる文字列の意味は常に同じではありません。

周りくどい解説になってしまいました。
例えば、コメントの種類を増やしてみましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package arraytestsample;
 
import java.math.BigDecimal;
 
public class BMI {
 
    private BigDecimal value;
 
    public BMI(int height, int weight) {
 
        BigDecimal workHeight = new BigDecimal(height);
        workHeight = workHeight.divide(new BigDecimal(100));
        workHeight = workHeight.multiply(workHeight);
 
        BigDecimal workWeight = new BigDecimal(weight);
        BigDecimal workBMI = workWeight.divide(workHeight, 2, BigDecimal.ROUND_HALF_UP);
 
        value = workBMI.setScale(1, BigDecimal.ROUND_HALF_UP);
    }
 
    public String getValue() {
        return value.toString();
    }
 
    public String getComment() {
        if (value.doubleValue() > 24) {
            return "肥満の可能性があります";
        } else if (value.doubleValue() < 18.5) {
            return "痩せている可能性があります";
        } else if (value.doubleValue() > 22) {
            return "標準ですが、やや肥満に近い数値です";
        } else {
            return "標準的と思われます";
        }
    }
}
package arraytestsample;

import java.math.BigDecimal;

public class BMI {

    private BigDecimal value;

    public BMI(int height, int weight) {

        BigDecimal workHeight = new BigDecimal(height);
        workHeight = workHeight.divide(new BigDecimal(100));
        workHeight = workHeight.multiply(workHeight);

        BigDecimal workWeight = new BigDecimal(weight);
        BigDecimal workBMI = workWeight.divide(workHeight, 2, BigDecimal.ROUND_HALF_UP);

        value = workBMI.setScale(1, BigDecimal.ROUND_HALF_UP);
    }

    public String getValue() {
        return value.toString();
    }

    public String getComment() {
        if (value.doubleValue() > 24) {
            return "肥満の可能性があります";
        } else if (value.doubleValue() < 18.5) {
            return "痩せている可能性があります";
        } else if (value.doubleValue() > 22) {
            return "標準ですが、やや肥満に近い数値です";
        } else {
            return "標準的と思われます";
        }
    }
}

標準の範囲内に「標準ですが、やや肥満に近い数値です」という判定を追加しました。

1
2
3
4
5
6
7
8
9
10
11
package arraytestsample;
 
public class ArrayTestSample {
 
    public static void main(String[] args) {
        BMI bmi = new BMI(160, 58);
        System.out.println("BMIの値は:" + bmi.getValue());
        System.out.println("BMI値による傾向は:" + bmi.getComment());
    }
    
}
package arraytestsample;

public class ArrayTestSample {

    public static void main(String[] args) {
        BMI bmi = new BMI(160, 58);
        System.out.println("BMIの値は:" + bmi.getValue());
        System.out.println("BMI値による傾向は:" + bmi.getComment());
    }
    
}

上記のようにパラメータを渡すと今までとは違った結果が得られます。
BMIの値は:22.7
BMI値による傾向は:標準ですが、やや肥満に近い数値です

JUnitコードも合わせて修正します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package arraytestsample;
 
import org.junit.Test;
import static org.junit.Assert.*;
 
public class BMITest {
 
    public BMITest() {
    }
 
    @Test
    public void testFat() {
        BMI bmi = new BMI(160, 62);
        assertEquals("24.2", bmi.getValue());
        assertEquals("肥満の可能性があります", bmi.getComment());
    }
 
    @Test
    public void testSlim() {
        BMI bmi = new BMI(160, 47);
        assertEquals("18.4", bmi.getValue());
        assertEquals("痩せている可能性があります", bmi.getComment());
    }
 
    @Test
    public void testNormalFat() {
        BMI bmi = new BMI(160, 61);
        assertEquals("23.8", bmi.getValue());
        assertEquals("標準ですが、やや肥満に近い数値です", bmi.getComment());
    }
 
    @Test
    public void testNormal() {
        BMI bmi = new BMI(160, 55);
        assertEquals("21.5", bmi.getValue());
        assertEquals("標準的と思われます", bmi.getComment());
    }
}
package arraytestsample;

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

public class BMITest {

    public BMITest() {
    }

    @Test
    public void testFat() {
        BMI bmi = new BMI(160, 62);
        assertEquals("24.2", bmi.getValue());
        assertEquals("肥満の可能性があります", bmi.getComment());
    }

    @Test
    public void testSlim() {
        BMI bmi = new BMI(160, 47);
        assertEquals("18.4", bmi.getValue());
        assertEquals("痩せている可能性があります", bmi.getComment());
    }

    @Test
    public void testNormalFat() {
        BMI bmi = new BMI(160, 61);
        assertEquals("23.8", bmi.getValue());
        assertEquals("標準ですが、やや肥満に近い数値です", bmi.getComment());
    }

    @Test
    public void testNormal() {
        BMI bmi = new BMI(160, 55);
        assertEquals("21.5", bmi.getValue());
        assertEquals("標準的と思われます", bmi.getComment());
    }
}

テストを実行します。

Testsuite: arraytestsample.BMITest
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.376 sec

テストも正常に実行できました。
でも、テストメソッドをいちいち増やしていくのはだるいな…。
もっと楽な方法はないのか?
次回への宿題にしたいと思います。
(長くなってしまいましたので一旦区切る意味でも)
それでは、また。