Python で assertEqual と assertEquals
ソフトウェアを構築する際には、コードを使用してビジネスロジックを実装する必要があります。
すべてのロジックと制約を確実に実装するために、プログラムで assert ステートメントを使用します。大規模なアプリケーションでは、Python の assertEquals()
および assertEqual()
メソッドを使用して単体テストを使用します。
Python で assert
ステートメントがどのように機能するかについて説明します。また、assertEquals()
および assertEqual()
メソッドを使用して、Python でビジネスロジックと制約を実装する方法についても説明します。
Python の assert
文とは
Python では、assert
ステートメントは式が True
または False
であるかどうかをチェックします。assert ステートメントの構文は次のとおりです。
assert conditional_expression
ここでは、assert
がキーワードです。conditional_expression
は、ステートメントを True
または False
として評価する条件付きステートメントです。
condition_expression
が True
と評価された場合、プログラムの実行は次のステートメントに進みます。反対に、conditional_expression
が False
と評価された場合、プログラムは AssertionError
例外を発生させます。
これらすべてを以下で見ることができます。
num1 = 10
num2 = 5
num3 = 10
print("This statement will get printed")
assert num1 == num3
print(
"This statement will also get printed as the expression in the above assert statement is True."
)
assert num2 == num3
print(
"This statement will not get printed as the expression in the above assert statement is False. This line of code is unreachable."
)
出力:
This statement will get printed
This statement will also get printed as the expression in the above assert statement is True.
Traceback (most recent call last):
File "tempy.py", line 9, in <module>
assert num2 == num3
AssertionError
ここでは、最初の print ステートメントが自動的に実行されることがわかります。
ステートメント assert num1 == num3
は、10==10
が True
と評価されるため、エラーを発生させません。したがって、2 番目の print ステートメントも実行されます。
その後、ステートメント"assert num2 == num3"
は、5==10
が False
と評価されるときに AssertionError
を発生させます。このため、プログラムの実行は停止し、3 番目の print ステートメントは実行されません。
AssertionError
例外が発生したときにメッセージを表示することもできます。このために、次の構文を使用します。
assert conditional_expression, message
ここで、message
は、conditional_expression
が False
と評価され、AssertionError
が発生したときに出力される文字列です。これは以下で確認できます。
num1 = 10
num2 = 5
num3 = 10
print("This statement will get printed")
assert num1 == num3, "{} is not equal to {}".format(num1, num2)
print(
"This statement will also get printed as the expression in the above assert statement is True."
)
assert num2 == num3, "{} is not equal to {}".format(num2, num3)
print(
"This statement will not get printed as the expression in the above assert statement is False. This line of code is unreachable."
)
出力:
This statement will get printed
This statement will also get printed as the expression in the above assert statement is True.
Traceback (most recent call last):
File "tempy.py", line 9, in <module>
assert num2 == num3, "{} is not equal to {}".format(num2, num3)
AssertionError: 5 is not equal to 10
AssertionError
を通知した後、出力 5 is not equal to 10
も出力されます。これらのタイプのメッセージを含めると、AssertionError
例外が発生するたびにメッセージを使用して要件を通知できるため、プログラムの機能をより簡単にテストできます。
assert ステートメントを使用して、制約を適用したり、Python でビジネスロジックを実装したりできます。ただし、assert ステートメントを使用することには欠点があります。assert
ステートメントの条件ステートメントが False
と評価されると、プログラムの実行が停止します。
したがって、何千もの制約と条件を持つ大規模なプログラムでは、AssertionError
例外が発生する回数だけプログラムを実行する必要があります。
これを克服するために、前述のように assertEquals()
または assertEqual()
ステートメントを使用できます。
Python の assertEquals()
メソッド
ソフトウェアに制約とビジネスロジックを適用するために、unittest
モジュールを使用できます。
unittest
モジュールは、制約を適用するために使用できる多くのメソッドを提供します。同等性のアサーションを実装するには、assertEquals()
メソッドと assertEqual()
メソッドを使用できます。
assertEquals()
メソッドを使用して同等性のアサーションを実装するには、最初に、unittest
モジュールで定義された TestCase
クラスのサブクラスであるクラスを作成します。次に、assertEquals()
メソッドの次の構文を使用して、等式のアサーションを定義できます。
self.assertEquals(self, first, second)
ここで、パラメータ first
は最初の値を入力引数として受け入れます。パラメータ second
は、入力引数として 2 番目の値を受け入れます。
パラメータ first
がパラメータ second
の値と等しい場合、単体テストは正常に合格します。それ以外の場合は、現在の行で AssertionError
例外が発生し、ユーザーにエラーが通知されます。
したがって、テストケースは失敗しますが、assert
ステートメントの場合のようにプログラムの実行は停止しません。プログラムはすべてのテストケースを実行してから、開発者にすべてのエラーを通知します。
これは以下で確認できます。
import unittest
class Tester(unittest.TestCase):
def setUp(self):
self.num1 = 10
self.num2 = 5
self.num3 = 10
def tearDown(self):
print("\nTest case completed. Result:")
def test_condition1(self):
self.assertEquals(self.num1, self.num3)
def test_condition2(self):
self.assertEquals(self.num2, self.num3)
if __name__ == "__main__":
unittest.main()
出力:
/home/aditya1117/PycharmProjects/pythonProject/webscraping.py:14: DeprecationWarning: Please use assertEqual instead.
self.assertEquals(self.num1, self.num3)
.F
======================================================================
FAIL: test_condition2 (__main__.Tester)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/aditya1117/PycharmProjects/pythonProject/webscraping.py", line 17, in test_condition2
self.assertEquals(self.num2, self.num3)
AssertionError: 5 != 10
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
Test case completed. Result:
Test case completed. Result:
ここで、unittest.main()
メソッドを実行すると、Tester
クラスのインスタンスが作成されます。その後、setUp()
メソッドが実行されます。setUp()
メソッドは変数を初期化し、他のモジュールからテスター
クラスに値をインポートします。
また、メソッド test_condition1()
および test_condition2()
が実装されていることも確認できます。ここでは、condition1
と condition2
という名前の前に test_
を含めて、これらのメソッドがテストケースを実施するために使用されていることをインタプリタに理解させています。
test_
で始まるメソッド名を指定しない場合、メソッドは Python インタープリターによって実行されません。
tearDown()
メソッドは、すべてのテストケースの後に実行されます。このメソッドを使用して、変数やその他の値を再初期化できます。
すべてのテストケースを実行した後、結果はテストケースが失敗したことを示しています。assertEquals()
メソッドが AssertionError
例外を発生させる(つまり、テストケースが失敗する)たびに、オプションのメッセージを出力することもできます。
このため、以下に示すように、メッセージ文字列を 3 番目の入力引数として assertEquals()
メソッドに渡す必要があります。
import unittest
class Tester(unittest.TestCase):
def setUp(self):
self.num1 = 10
self.num2 = 5
self.num3 = 10
def tearDown(self):
print("\nTest case completed. Result:")
def test_condition1(self):
message = "{} is not equal to {}".format(self.num1, self.num3)
self.assertEquals(self.num1, self.num3, message)
def test_condition2(self):
message = "{} is not equal to {}".format(self.num2, self.num3)
self.assertEquals(self.num2, self.num3, message)
if __name__ == "__main__":
unittest.main()
出力:
Test case completed. Result:
Test case completed. Result:
/home/aditya1117/PycharmProjects/pythonProject/webscraping.py:15: DeprecationWarning: Please use assertEqual instead.
self.assertEquals(self.num1, self.num3,message)
.F
======================================================================
FAIL: test_condition2 (__main__.Tester)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/aditya1117/PycharmProjects/pythonProject/webscraping.py", line 19, in test_condition2
self.assertEquals(self.num2, self.num3,message)
AssertionError: 5 != 10 : 5 is not equal to 10
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
ここでは、2 番目のテストケースが失敗したときに、インタプリタが 5 は 10 に等しくありません
というメッセージも出力することがわかります。
assertEquals()
メソッドは 2010 年に廃止されました。したがって、assertEquals()
メソッドを使用しているときに、メソッドが廃止されたという警告が表示され、DeprecationWarning: Please use assertEqual instead
というメッセージが表示されます。
Python が assertEqual()
メソッドの使用を提案しているので、それを使用して Python で同等性のアサーションを実装しましょう。
Python の assertEqual()
メソッド
名前に s
が含まれていることを除けば、assertEqual()
メソッドの動作は assertEquals()
メソッドと完全に似ています。両方のメソッドの構文も同じです。
したがって、次のように、assertEquals()
メソッドの代わりに assertEqual()
メソッドを使用できます。
import unittest
class Tester(unittest.TestCase):
def setUp(self):
self.num1 = 10
self.num2 = 5
self.num3 = 10
def tearDown(self):
print("\nTest case completed. Result:")
def test_condition1(self):
self.assertEqual(self.num1, self.num3)
def test_condition2(self):
self.assertEqual(self.num2, self.num3)
if __name__ == "__main__":
unittest.main()
出力:
.F
======================================================================
FAIL: test_condition2 (__main__.Tester)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/aditya1117/PycharmProjects/pythonProject/webscraping.py", line 17, in test_condition2
self.assertEqual(self.num2, self.num3)
AssertionError: 5 != 10
----------------------------------------------------------------------
Ran 2 tests in 0.000s
FAILED (failures=1)
Test case completed. Result:
Test case completed. Result:
Process finished with exit code 1
出力では、プログラムが前のコードと同じように機能することがわかります。また、減価償却についての警告は受けていません。
次のように、テストケースにメッセージを追加できます。
import unittest
class Tester(unittest.TestCase):
def setUp(self):
self.num1 = 10
self.num2 = 5
self.num3 = 10
def tearDown(self):
print("\nTest case completed. Result:")
def test_condition1(self):
message = "{} is not equal to {}".format(self.num1, self.num3)
self.assertEqual(self.num1, self.num3, message)
def test_condition2(self):
message = "{} is not equal to {}".format(self.num2, self.num3)
self.assertEqual(self.num2, self.num3, message)
if __name__ == "__main__":
unittest.main()
出力:
.F
======================================================================
FAIL: test_condition2 (__main__.Tester)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/aditya1117/PycharmProjects/pythonProject/webscraping.py", line 19, in test_condition2
self.assertEqual(self.num2, self.num3, message)
AssertionError: 5 != 10 : 5 is not equal to 10
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
Test case completed. Result:
Test case completed. Result:
この記事では、unittest
モジュールで定義された TestCase
クラスのサブクラスを実装して、assertEquals()
メソッドと assertEqual()
メソッドを使用していることを確認できます。
Django フレームワークを使用してプログラムを開発しているときに、Django.test
モジュールで定義された TestCase
クラスのサブクラスを実装してしまう可能性があります。このような場合、プログラムは以下のようにエラーになります。
import unittest
from django.test import TestCase
class Tester(TestCase):
def setUp(self):
self.num1 = 10
self.num2 = 5
self.num3 = 10
def tearDown(self):
print("\nTest case completed. Result:")
def test_condition1(self):
message = "{} is not equal to {}".format(self.num1, self.num3)
self.assertEqual(self.num1, self.num3, message)
def test_condition2(self):
message = "{} is not equal to {}".format(self.num2, self.num3)
self.assertEqual(self.num2, self.num3, message)
if __name__ == "__main__":
unittest.main()
出力:
E
======================================================================
ERROR: setUpClass (__main__.Tester)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/aditya1117/.local/lib/python3.8/site-packages/django/test/testcases.py", line 1201, in setUpClass
super().setUpClass()
File "/home/aditya1117/.local/lib/python3.8/site-packages/django/test/testcases.py", line 187, in setUpClass
cls._add_databases_failures()
File "/home/aditya1117/.local/lib/python3.8/site-packages/django/test/testcases.py", line 209, in _add_databases_failures
cls.databases = cls._validate_databases()
File "/home/aditya1117/.local/lib/python3.8/site-packages/django/test/testcases.py", line 195, in _validate_databases
if alias not in connections:
File "/home/aditya1117/.local/lib/python3.8/site-packages/django/utils/connection.py", line 73, in __iter__
return iter(self.settings)
File "/home/aditya1117/.local/lib/python3.8/site-packages/django/utils/functional.py", line 48, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/home/aditya1117/.local/lib/python3.8/site-packages/django/utils/connection.py", line 45, in settings
self._settings = self.configure_settings(self._settings)
File "/home/aditya1117/.local/lib/python3.8/site-packages/django/db/utils.py", line 144, in configure_settings
databases = super().configure_settings(databases)
File "/home/aditya1117/.local/lib/python3.8/site-packages/django/utils/connection.py", line 50, in configure_settings
settings = getattr(django_settings, self.settings_name)
File "/home/aditya1117/.local/lib/python3.8/site-packages/django/conf/__init__.py", line 84, in __getattr__
self._setup(name)
File "/home/aditya1117/.local/lib/python3.8/site-packages/django/conf/__init__.py", line 65, in _setup
raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: Requested setting DATABASES, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
----------------------------------------------------------------------
Ran 0 tests in 0.003s
FAILED (errors=1)
ここでは、django.test
モジュールの TestCase
クラスを使用すると、プログラムでエラーが発生することがわかります。したがって、テストケースは実行されません。
したがって、Django.test
モジュールではなく、unittest モジュールで定義された TestCase
クラスを常に使用するようにしてください。
まとめ
アプリケーションをテストするために、assert
ステートメント、assertEquals()
、および assertEqual()
メソッドを使用することについて説明しました。
ここで、assert
ステートメントと assertEqual()
メソッドを実稼働環境の実際のアプリケーションで使用できないことを覚えておくと役に立ちます。これらのメソッドを使用して、本番環境にコードをデプロイする前にアプリケーションをテストすることしかできません。
また、assertEquals()
メソッドの代わりに assertEqual()
メソッドを使用するようにしてください。後者は Python プログラミング言語で非推奨になっているためです。
Aditya Raj is a highly skilled technical professional with a background in IT and business, holding an Integrated B.Tech (IT) and MBA (IT) from the Indian Institute of Information Technology Allahabad. With a solid foundation in data analytics, programming languages (C, Java, Python), and software environments, Aditya has excelled in various roles. He has significant experience as a Technical Content Writer for Python on multiple platforms and has interned in data analytics at Apollo Clinics. His projects demonstrate a keen interest in cutting-edge technology and problem-solving, showcasing his proficiency in areas like data mining and software development. Aditya's achievements include securing a top position in a project demonstration competition and gaining certifications in Python, SQL, and digital marketing fundamentals.
GitHub