アサーションの重要な役割を理解するための実際の例は何ですか?
アサーションの重要な役割を理解するための実際の例は何ですか?
回答:
アサーション(assertキーワードによる)はJava 1.4で追加されました。これらは、コード内の不変条件の正しさを検証するために使用されます。これらは本番用コードでトリガーされることはなく、バグまたはコードパスの誤用を示しています。これらは-ea
、java
コマンドのオプションを使用して実行時にアクティブ化できますが、デフォルトではオンになっていません。
例:
public Foo acquireFoo(int id) {
Foo result = null;
if (id > 50) {
result = fooService.read(id);
} else {
result = new Foo(id);
}
assert result != null;
return result;
}
assert
publicメソッドのパラメーター(docs.oracle.com/javase/1.4.2/docs/guide/lang/assert.html)のチェックに使用しないように指示しています。それはException
プログラムを殺すのではなく、スローするはずです。
This convention is unaffected by the addition of the assert construct. Do not use assertions to check the parameters of a public method. An assert is inappropriate because the method guarantees that it will always enforce the argument checks. It must check its arguments whether or not assertions are enabled. Further, the assert construct does not throw an exception of the specified type. It can throw only an AssertionError.
docs.oracle.com/javase/8/docs/technotes/guides/language/…– Bakhshi '26
あなたが原子力発電所を制御するプログラムを書くことになっていると仮定しましょう。最も小さな間違いでも壊滅的な結果をもたらす可能性があることは明らかであり、そのため、コードにはバグがない必要があります(引数のためにJVMにバグがないと仮定します)。
Javaは検証可能な言語ではありません。つまり、操作の結果が完全であることを計算することはできません。これの主な理由はポインターです:それらはどこでもどこでも指すことができるため、少なくともコードの妥当な範囲内では、この正確な値であると計算することはできません。この問題を考えると、コードが全体として正しいことを証明する方法はありません。しかし、あなたができることは、それが起こったときに少なくともすべてのバグを見つけたことを証明することです。
このアイデアは、契約による設計(DbC)パラダイムに基づいています。最初に(数学的な精度で)メソッドの実行内容を定義し、次に、実際の実行中にテストすることによってこれを検証します。例:
// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
return a + b;
}
これは問題なく機能することは明らかですが、ほとんどのプログラマーはこのバグの中に隠れたバグを見ることはありません(ヒント:Ariane Vは同様のバグのためにクラッシュしました)。現在、DbCでは、関数の入力と出力を常にチェックして、正しく機能したことを確認する必要があると定義しています。Javaはこれをアサーションを通じて実行できます。
// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
assert (Integer.MAX_VALUE - a >= b) : "Value of " + a + " + " + b + " is too large to add.";
final int result = a + b;
assert (result - a == b) : "Sum of " + a + " + " + b + " returned wrong sum " + result;
return result;
}
この関数が失敗した場合は、それに気づくでしょう。あなたはあなたのコードに問題があることを知っているでしょう、あなたはそれがどこにあるのか、そしてあなたはそれを引き起こした原因を知っています(例外と同様に)。さらに重要なことは、次のコードが間違った値で動作するのを防ぎ、制御するものに損傷を与える可能性があるときに、実行を停止することです。
Java例外も同様の概念ですが、すべての検証に失敗します。(実行速度を犠牲にして)さらに多くのチェックが必要な場合は、アサーションを使用する必要があります。そうするとコードが肥大化しますが、最終的には驚くほど短い開発時間で製品を提供できます(バグを早期に修正するほど、コストは低くなります)。さらに、コード内にバグがある場合は、それを検出します。バグがすり抜けて後で問題が発生することはありません。
これはバグのないコードを保証するものではありませんが、通常のプログラムよりもはるかに近いコードです。
new IllegalArgumentException
したのか、assertを使用する代わりに単にメッセージでa をスローすることの違いは何ですか?throws
つまり、メソッドの宣言とコードに追加して、その例外をどこかで管理することは別です。なぜassert
新しい例外を投げるのですか?または、if
代わりにではないのassert
ですか?これを実際に取得することはできません:(
a
は、負になる可能性がある場合は間違っています。2番目のアサーションは無意味です。int値の場合、常にa + b-b == aになります。そのテストは、コンピューターが根本的に壊れている場合にのみ失敗する可能性があります。この不測の事態を防ぐには、複数のCPU間で一貫性を確認する必要があります。
アサーションは、コードのバグをキャッチする開発段階のツールです。これらは簡単に削除できるように設計されているため、製品コードには存在しません。したがって、アサーションは、顧客に提供する「ソリューション」の一部ではありません。これらは、行っている仮定が正しいことを確認するための内部チェックです。最も一般的な例は、nullをテストすることです。多くのメソッドは次のように書かれています:
void doSomething(Widget widget) {
if (widget != null) {
widget.someMethod(); // ...
... // do more stuff with this widget
}
}
このようなメソッドでは、ウィジェットがnullにならないことがよくあります。したがって、それがnullの場合、追跡する必要があるコードのどこかにバグがあります。しかし、上記のコードはこれを決して教えません。したがって、「安全な」コードを作成するための善意のある取り組みでは、バグも隠しています。次のようなコードを記述する方がはるかに優れています。
/**
* @param Widget widget Should never be null
*/
void doSomething(Widget widget) {
assert widget != null;
widget.someMethod(); // ...
... // do more stuff with this widget
}
このようにして、このバグを早期にキャッチすることができます。(このパラメーターをnullにしないことをコントラクトで指定することも役立ちます。)開発中にコードをテストするときは、必ずアサーションをオンにしてください。(そして、これを行うようにあなたの同僚を説得することもしばしば困難であり、私はそれを非常に苛立たせます。)
さて、あなたの同僚の何人かはこのコードに異議を唱え、プロダクションでの例外を防ぐためにnullチェックを入れるべきだと主張します。その場合でも、アサーションは役に立ちます。次のように書くことができます:
void doSomething(Widget widget) {
assert widget != null;
if (widget != null) {
widget.someMethod(); // ...
... // do more stuff with this widget
}
}
このようにして、同僚はプロダクションコードにnullチェックがあることに満足しますが、開発中は、ウィジェットがnullのときにバグを非表示にすることはありません。
これが実際の例です。私はかつて、2つの任意の値が等しいかどうかを比較するメソッドを作成しました。
/**
* Compare two values using equals(), after checking for null.
* @param thisValue (may be null)
* @param otherValue (may be null)
* @return True if they are both null or if equals() returns true
*/
public static boolean compare(final Object thisValue, final Object otherValue) {
boolean result;
if (thisValue == null) {
result = otherValue == null;
} else {
result = thisValue.equals(otherValue);
}
return result;
}
このコードequals()
は、thisValueがnullでない場合のメソッドの処理を委譲します。ただし、nullパラメータを適切に処理することにより、equals()
メソッドがの規約を正しく満たすことを前提としていequals()
ます。
同僚が私のコードに異議を唱え、クラスの多くにequals()
nullをテストしないバグのあるメソッドがあるため、このメソッドにそのチェックを入れるべきだと私に言った。これが賢明な場合、またはエラーを強制する必要がある場合は議論の余地があります。エラーを特定して修正することができますが、私は同僚に延期し、コメントでマークしたnullチェックを入れました。
public static boolean compare(final Object thisValue, final Object otherValue) {
boolean result;
if (thisValue == null) {
result = otherValue == null;
} else {
result = otherValue != null && thisValue.equals(otherValue); // questionable null check
}
return result;
}
ここでの追加のチェックother != null
は、equals()
メソッドがその契約で要求されているnullのチェックに失敗した場合にのみ必要です。
バグのあるコードをコードベースに残すという知恵について、同僚と実りのない議論をするのではなく、コードに2つのアサーションを挿入するだけです。これらのアサーションは、開発フェーズ中に、クラスの1つがequals()
適切に実装されなかった場合に通知するため、修正できます。
public static boolean compare(final Object thisValue, final Object otherValue) {
boolean result;
if (thisValue == null) {
result = otherValue == null;
assert otherValue == null || otherValue.equals(null) == false;
} else {
result = otherValue != null && thisValue.equals(otherValue);
assert thisValue.equals(null) == false;
}
return result;
}
覚えておくべき重要な点は次のとおりです。
アサーションは開発段階のツールのみです。
アサーションの要点は、コードだけでなくコードベースにもバグがあるかどうかを知らせることです。(ここでのアサーションは、実際には他のクラスのバグにフラグを立てます。)
私のクラスが適切に記述されていると私の同僚が確信していたとしても、ここでのアサーションはまだ役に立ちます。nullのテストに失敗する可能性のある新しいクラスが追加され、このメソッドはこれらのバグにフラグを付けることができます。
開発では、作成したコードがアサーションを使用していない場合でも、常にアサーションをオンにする必要があります。私のIDEは、新しい実行可能ファイルに対して常にデフォルトでこれを行うように設定されています。
アサーションによって本番環境でのコードの動作が変更されることはないので、同僚はnullチェックが存在し、equals()
メソッドにバグがある場合でもこのメソッドが適切に実行されることを嬉しく思います。equals()
開発中にバグのあるメソッドを見つけられるので、私は幸せです。
また、失敗する一時的なアサーションを挿入することにより、アサーションポリシーをテストする必要があります。これにより、ログファイルまたは出力ストリームのスタックトレースを通じて通知されることを確認できます。
assert
キーワードが何をするかを説明する良い答えはたくさんありますが、実際の質問に答える人はほとんどいませassert
ん。
答え:ほとんどありません。
アサーションは、概念としては素晴らしいものです。良いコードがたくさんありif (...) throw ...
ステートメント(およびその親戚のようなObjects.requireNonNull
とはMath.addExact
)。ただし、特定の設計上の決定により、assert
キーワード自体の有用性が大幅に制限されています。
assert
キーワードの背後にある原動力となるアイデアは時期尚早の最適化であり、主な機能はすべてのチェックを簡単にオフにできることです。実際、assert
チェックはデフォルトでオフになっています。
ただし、本番環境では不変のチェックが引き続き行われることが非常に重要です。これは、完全なテストカバレッジは不可能であり、すべての製品コードには、アサーションが診断および軽減に役立つバグがあるためです。
したがって、の使用はif (...) throw ...
、パブリックメソッドのパラメーター値のチェックやのスローに必要なのと同じように、推奨されますIllegalArgumentException
。
ときどき、処理に望ましくないほど長い時間がかかる(そして問題になるほど頻繁に呼び出される)不変のチェックを作成したくなることがあります。ただし、このようなチェックはテストの速度を低下させるため、これも望ましくありません。このような時間のかかるチェックは、通常、単体テストとして記述されます。それにもかかわらず、assert
この理由で使用することが理にかなっている場合があります。
assert
それがよりきれいできれいだからという理由で使用しないでくださいif (...) throw ...
(そして私はきれいできれいなのが好きなので、非常に苦痛でそれを言います)。自分を助けることができず、アプリケーションの起動方法を制御できる場合は、自由に使用できますassert
が、本番環境では常にアサーションを有効にします。確かに、これは私がしがちなことです。私は原因となりますロンボク注釈を推進していますassert
より多くのように動作しますif (...) throw ...
。ここに投票してください。
(ラント:JVM開発者はひどい時期尚早に最適化されたコーダーの集まりでした。そのため、JavaプラグインとJVMの非常に多くのセキュリティ問題について聞いたのです。彼らは本番コードに基本的なチェックとアサーションを含めることを拒否し、私たちは続けています価格を支払う。)
catch (Throwable t)
です。などのOutOfMemoryError、AssertionErrorが、から回復/トラップ、ログ、または再試行しようとしない理由はない
assert
キーワードの実装が悪いです。概念ではなくキーワードを参照していることをより明確にするために、回答を編集します。
最も一般的な使用例を次に示します。列挙値をオンにするとします。
switch (fruit) {
case apple:
// do something
break;
case pear:
// do something
break;
case banana:
// do something
break;
}
すべてのケースを処理する限り、大丈夫です。しかし、いつか誰かがenumにfigを追加し、switchステートメントに追加するのを忘れます。これにより、switchステートメントを終了するまで効果が感じられないため、検出が難しいバグが生成されます。しかし、このようにスイッチを書くと、すぐにそれをキャッチできます:
switch (fruit) {
case apple:
// do something
break;
case pear:
// do something
break;
case banana:
// do something
break;
default:
assert false : "Missing enum value: " + fruit;
}
AssertionError
により、アサーションが有効な場合にがスローされ-ea
ます()。本番環境で望ましい動作は何ですか?サイレントノーオペレーションと潜在的な災害は、後で実行されますか?おそらく違います。私は明示的に提案するでしょうthrow new AssertionError("Missing enum value: " + fruit);
。
default
では、コンパイラーが欠落しているケースについて警告できるように、使用すべきではありません。あなたはできるreturn
の代わりにbreak
(これは、メソッドを抽出する必要がある場合があります)、その後、スイッチの後に不足している場合を扱います。このようにして、警告との両方の機会を得assert
ます。
アサーションは、事後条件と「失敗してはならない」事前条件をチェックするために使用されます。正しいコードはアサーションを失敗させるべきではありません。彼らがトリガーしたとき、彼らはバグを示すべきです(うまくいけば、問題の実際の場所がある場所に近い場所にあります)。
アサーションの例としては、メソッドの特定のグループが正しい順序で呼び出されていることを確認することが挙げられます(たとえば、それhasNext()
がの前next()
に呼び出されますIterator
)。
Javaのassertキーワードは何をしますか?
コンパイルされたバイトコードを見てみましょう。
私たちはそれを結論付けます:
public class Assert {
public static void main(String[] args) {
assert System.currentTimeMillis() == 0L;
}
}
以下とほぼ同じバイトコードを生成します。
public class Assert {
static final boolean $assertionsDisabled =
!Assert.class.desiredAssertionStatus();
public static void main(String[] args) {
if (!$assertionsDisabled) {
if (System.currentTimeMillis() != 0L) {
throw new AssertionError();
}
}
}
}
ここAssert.class.desiredAssertionStatus()
でtrue
、-ea
はコマンドラインで渡される場合で、それ以外の場合はfalseです。
System.currentTimeMillis()
最適化されないようにするために使用します(assert true;
そうしました)。
合成フィールドが生成されるので、Java Assert.class.desiredAssertionStatus()
はロード時に一度だけ呼び出す必要があり、その結果がそこにキャッシュされます。参照:「静的合成」の意味は何ですか?
次の方法で確認できます。
javac Assert.java
javap -c -constants -private -verbose Assert.class
Oracle JDK 1.8.0_45では、合成静的フィールドが生成されました(「静的合成」の意味は何ですか?):
static final boolean $assertionsDisabled;
descriptor: Z
flags: ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
静的初期化子と一緒に:
0: ldc #6 // class Assert
2: invokevirtual #7 // Method java/lang Class.desiredAssertionStatus:()Z
5: ifne 12
8: iconst_1
9: goto 13
12: iconst_0
13: putstatic #2 // Field $assertionsDisabled:Z
16: return
そして主な方法は:
0: getstatic #2 // Field $assertionsDisabled:Z
3: ifne 22
6: invokestatic #3 // Method java/lang/System.currentTimeMillis:()J
9: lconst_0
10: lcmp
11: ifeq 22
14: new #4 // class java/lang/AssertionError
17: dup
18: invokespecial #5 // Method java/lang/AssertionError."<init>":()V
21: athrow
22: return
私たちはそれを結論付けます:
assert
。これはJava言語の概念ですassert
コマンドラインで-Pcom.me.assert=true
置き換えるシステムプロパティ-ea
とthrow new AssertionError()
。catch (Throwable t)
条項はアサーション違反もキャッチできますか?私にとって、その有用性はアサーションの本体に時間がかかるケースに限られています。
AssertionError
最初のものをキャッチして再スローするだけです。
Stackクラスからの実際の例(Java ArticlesのAssertionから)
public int pop() {
// precondition
assert !isEmpty() : "Stack is empty";
return stack[--num];
}
アサーションにより、コードの欠陥を検出できます。プログラムの運用中には、アサーションをオフにしたままテストとデバッグのアサーションをオンにすることができます。
それが真実であるとわかっているのに、なぜそれを主張するのですか?すべてが正しく機能している場合にのみ当てはまります。プログラムに欠陥がある場合、それは実際には真実ではない可能性があります。プロセスの早い段階でこれを検出すると、何かが間違っていることがわかります。
assert
声明はオプションと一緒にこの文が含まれているString
メッセージ。
assertステートメントの構文には2つの形式があります。
assert boolean_expression;
assert boolean_expression: error_message;
アサーションを使用する場所と使用しない場所を管理するいくつかの基本的なルールを次に示します。アサーションは次の場合に使用する必要があります。
プライベートメソッドの入力パラメーターを検証しています。パブリックメソッド用ではありません。public
メソッドは、不正なパラメータが渡されたときに通常の例外をスローする必要があります。
ほぼ間違いなく真実である事実の妥当性を保証するためのプログラムのどこか。
たとえば、1または2のどちらかだけであることが確実な場合は、次のようなアサーションを使用できます。
...
if (i == 1) {
...
}
else if (i == 2) {
...
} else {
assert false : "cannot happen. i is " + i;
}
...
アサーションは次の場合には使用しないでください。
パブリックメソッドの入力パラメーターを検証しています。アサーションは常に実行されるとは限らないため、通常の例外メカニズムを使用する必要があります。
ユーザーが入力したものに対する制約の検証。同上。
副作用には使用しないでください。
たとえば、ここではアサーションがdoSomething()
メソッドの呼び出しの副作用として使用されるため、これは適切な使用ではありません。
public boolean doSomething() {
...
}
public void someMethod() {
assert doSomething();
}
これが正当化される唯一のケースは、コードでアサーションが有効になっているかどうかを調べようとしている場合です。
boolean enabled = false;
assert enabled = true;
if (enabled) {
System.out.println("Assertions are enabled");
} else {
System.out.println("Assertions are disabled");
}
ここで提供されるすべての優れた回答に加えて、公式のJava SE 7プログラミングガイドには、使用に関するかなり簡潔なマニュアルがありassert
ます。アサーションを使用するのが良い(そして重要なことに、悪い)アイデアであるときのいくつかの実例と、それが例外をスローすることとの違い
アサートは開発時に非常に役立ちます。コードが正しく機能しているのに何かが起こらない場合に使用します。使い方は簡単で、コード内にとどまることができます。実際にはオフになっているからです。
この状態が実際に発生する可能性がある場合は、対処する必要があります。
気に入っていますが、Eclipse / Android / ADTで有効にする方法がわかりません。デバッグ中でもオフのようです。(これにはスレッドがありますが、ADT実行構成には表示されない「Java vm」を指します)。
これが、Hibernate / SQLプロジェクト用にサーバーに書き込んだアサーションです。エンティティBeanには、isActiveとisDefaultと呼ばれる2つの実質的にブール値のプロパティがありました。それぞれが「Y」、「N」、または「N」として扱われるnullの値を持つことができます。ブラウザクライアントがこれらの3つの値に制限されていることを確認します。したがって、これら2つのプロパティのセッターに、このアサーションを追加しました。
assert new HashSet<String>(Arrays.asList("Y", "N", null)).contains(value) : value;
次のことに注意してください。
このアサーションは開発フェーズのみを対象としています。クライアントが不正な値を送信した場合、本番環境に到達するずっと前に、それを早期にキャッチして修正します。アサーションは、早期に検出できる欠陥に対するものです。
このアサーションは遅く、非効率的です。大丈夫。アサーションは遅くてもかまいません。それらは開発専用のツールであるため、私たちは気にしません。アサーションが無効になるため、これによって本番コードが遅くなることはありません。(この点については不一致があります。これについては後で説明します。)これが私の次の点につながります。
このアサーションには副作用はありません。変更不可能な静的な最終セットに対して自分の値をテストすることもできましたが、そのセットは本番環境に残り、使用されることはありませんでした。
このアサーションは、クライアントの適切な操作を確認するために存在します。したがって、本番環境に到達するまでに、クライアントが適切に動作していることが確認されるため、安全にアサーションをオフにできます。
一部の人々はこれを尋ねます:アサーションが本番環境で必要ない場合、なぜ終わったらそれらを単に取り出しないのですか?次のバージョンに取り掛かるときにも必要になるからです。
一部の人々は、アサーションを使用すべきではないと主張しています。なぜなら、すべてのバグがなくなったことを確認することはできないため、本番環境でもバグを維持する必要があるからです。そして、assertステートメントを使用しても意味がありません。assertの唯一の利点は、それらをオフにできることです。したがって、この考え方によると、アサートは(ほとんど)使用しないでください。同意しません。テストが本番環境に属している場合は、アサートを使用しないでください。しかし、このテストは本番環境には属していません。これは、本番環境に到達する可能性が低いバグをキャッチするためのものなので、完了したら安全にオフにすることができます。
ところで、私はそれをこのように書くことができたでしょう:
assert value == null || value.equals("Y") || value.equals("N") : value;
これは3つの値に対してのみ問題ありませんが、可能な値の数が増えると、HashSetバージョンがより便利になります。私は、効率性を強調するためにHashSetバージョンを選択しました。
HashSet
を使用すると、に比べて速度が向上することを強く疑いArrayList
ます。さらに、セットとリストの作成がルックアップ時間を支配します。定数を使用する場合は問題ありません。それはすべて言った、+ 1。
アサーションは基本的にアプリケーションのデバッグに使用されます。または、アプリケーションの有効性をチェックするために、一部のアプリケーションの例外処理の代わりに使用されます。
アサーションは実行時に機能します。概念全体を非常に簡単に説明できる簡単な例を以下に示します。assertキーワードはJavaで何をしますか?(WikiAnswers)。
アサーションはデフォルトで無効になっています。それらを有効にするには、-ea
オプションを指定してプログラムを実行する必要があります(粒度は変更可能です)。たとえば、java -ea AssertionsDemo
。
アサーションを使用するための2つの形式があります。
assert 1==2; // This will raise an AssertionError
。assert 1==2: "no way.. 1 is not equal to 2";
これは、指定されたメッセージも表示してAssertionErrorを発生させるため、より優れています。実際の構文ではassert expr1:expr2
、expr2は値を返す任意の式にすることができますが、メッセージを出力するためだけに頻繁に使用しています。要約すると(これはJavaだけでなく多くの言語にも当てはまります):
「アサート」は、主にソフトウェア開発者がデバッグプロセス中にデバッグ補助として使用します。アサートメッセージは表示されません。多くの言語では、「本番」コードの生成に使用するために、すべての「アサート」を無視するコンパイル時オプションを提供しています。
「例外」は、論理エラーを表すかどうかに関係なく、あらゆる種類のエラー条件を処理するための便利な方法です。なぜなら、続行できないようなエラー条件に遭遇した場合は、単に「空中に投げて、 「どこにいても、他の誰かがそれらを「キャッチ」する準備ができていることを期待しています。制御は、例外をスローしたコードからキャッチャーのミットに直接、1つのステップで転送されます。(そして、キャッチャーは行われた呼び出しの完全なバックトレースを見ることができます。)
さらに、そのサブルーチンの呼び出し元は、サブルーチンが成功したかどうかを確認する必要はありません。「ここにいる場合は、成功している必要があります。それ以外の場合は、例外がスローされてここにいないからです!」この単純な戦略により、コードの設計とデバッグがはるかに簡単になります。
例外により、致命的なエラー条件を「ルールの例外」とすることができます。そして、それらが「ルールの例外... 「フライボール!」でもあるコードパスによって処理されるようにします。
アサーションは、オフになる可能性のあるチェックです。それらはめったに使用されません。どうして?
result != null
このようなチェックは非常に高速であり、保存するものはほとんどないため、単純なチェックには使用しないでください。だから、何が残っていますか?本当に真であると期待される状態の高価なチェック。良い例は、RBツリーのようなデータ構造の不変条件です。実際、JDK8では、このような意味のあるアサートがいくつかあります。ConcurrentHashMap
TreeNodes
時々、小切手は本当に高価ではありませんが、同時に、あなたはかなり確かです、それは合格します。私のコードには、たとえば、
assert Sets.newHashSet(userIds).size() == userIds.size();
ここで、作成したリストに一意の要素があることは確かですが、文書化して再確認したかったのです。
基本的に、「trueをアサート」は成功し、「falseをアサート」は失敗します。これがどのように機能するかを見てみましょう:
public static void main(String[] args)
{
String s1 = "Hello";
assert checkInteger(s1);
}
private static boolean checkInteger(String s)
{
try {
Integer.parseInt(s);
return true;
}
catch(Exception e)
{
return false;
}
}
assert
キーワードです。JDK 1.4で導入されました。2種類がありassert
、S
assert
ステートメントassert
ステートメント。デフォルトでは、すべてのassert
ステートメントは実行されません。場合assert
文が偽受け、それが自動的にアサーションエラーが発生します。