テストとかでassertEqualsにdoubleを指定するときは注意


Javaを勉強中で、自分で練習プログラムを組むときにテストを作ったほうが確認になると思って挑戦しています。

テストを作成しているときに、エラーが発生したので「なんでかなー」といろいろ調べていたら、理解が進んだのでまとめてみました。

今回のプログラム

今回作成したプログラムは、よくあるBMIを算出するやつです。

study.java
public class study {
    public static void main(String[] args) {
    }

    public static double calcBMI(int weight, double height){
        double BMI;
        BMI = weight / height / height;
        return BMI;
    }

これに対してテストプログラムを作成。

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

public class studyTest {
    @Test
    public void calcBMI() {
        assertEquals(21.798202394816208, drill01.calcBMI(73, 1.83));
    }
}

IntelliJ上だとこんな感じ。項目の解説が出るのでわかりやすい。

いったんテスト実行

この時点でなんかエラーが出てるけど、気にせずこのテストコードをとりあえず実行してみます。
するとエラー発生、
java.lang.AssertionError: Use assertEquals(expected, actual, delta) to compare floating-point numbers
と言われました。

定石通りに、エラーコードをググります。
だいたいエラー全文でググると英語の記事とか質疑応答ばっかり出てくるんだよなー。と思ってたら、それっぽい日本語記事を発見しました。(英語勉強しよ・・・)

どうやらdouble型を比較するときには誤差を考慮に入れる必要があり、assertEqualsで取り扱うときは引数に許容値を設定する必要があるようです。

double型のアサーションにおける罠 | DevelopersIO

Assert#assetEqualsメソッドを使う
JUnit3系のメソッドですが、assetEqualsメソッドを利用して比較することができます。ただし、assetEquals(double, double)は非推奨となっており、assetEquals(double, double, double)を利用してください。3つ目の引数には比較する時に許容する誤差を指定します。+0.0と-0.0の比較であれば誤差は0で良いので、次のように記述できます。
assertEquals(+0.0, -0.0, 0.0);

それを知ってからエラーを改めて読んでみるとなるほど、書いてあるように
Use assertEquals(expected, actual, delta) to compare floating-point numbers
↓Google翻訳
浮動小数点数を比較するにはassertEquals(expected、actual、delta)を使います。

ということでdeltaの位置に誤差を指定する必要があったようです。

実際に引数を追加してみると、


ということで、テストを無事実行できました。めでたしめでたし。