私はPythonでのユニットテスト、特にunittest
モジュールを学ぼうとしていました。
次の行を検討してください。
_import unittest
class abc(unittest.TestCase):
def xyz():
...
if __name__ == "__main__":
unittest.main()
_
unittest.main()
を呼び出したため、すべてのテストケースが実行されていることがわかりました。
この呼び出しによってすべてのテストケースがどのように実行されるのか知りたいと思いました。
私はすべてのテストクラスについて_unittest.TestCase
_から継承しているので、すべての魔法を実行していることを知っています。洞察はありますか?
unittestに関連付けられているメインは、実際にはTestProgramのインスタンスであり、インスタンス化されるとすべてのテストを実行します。
以下は、ユニットテストソースからコピーされた関連コードです http://pythonhosted.org/gchecky/unittest-pysrc.html :
_735 class TestProgram:
752 - def __init__(self, module='__main__', defaultTest=None,
753 argv=None, testRunner=None, testLoader=defaultTestLoader):
754 if type(module) == type(''):
755 self.module = __import__(module)
756 for part in module.split('.')[1:]:
757 self.module = getattr(self.module, part)
758 else:
759 self.module = module
760 if argv is None:
761 argv = sys.argv
762 self.verbosity = 1
763 self.defaultTest = defaultTest
764 self.testRunner = testRunner
765 self.testLoader = testLoader
766 self.progName = os.path.basename(argv[0])
767 self.parseArgs(argv)
768 self.runTests()
769
770 - def usageExit(self, msg=None):
771 if msg: print msg
772 print self.USAGE % self.__dict__
773 sys.exit(2)
774
775 - def parseArgs(self, argv):
776 import getopt
777 try:
778 options, args = getopt.getopt(argv[1:], 'hHvq',
779 ['help','verbose','quiet'])
780 for opt, value in options:
781 if opt in ('-h','-H','--help'):
782 self.usageExit()
783 if opt in ('-q','--quiet'):
784 self.verbosity = 0
785 if opt in ('-v','--verbose'):
786 self.verbosity = 2
787 if len(args) == 0 and self.defaultTest is None:
788 self.test = self.testLoader.loadTestsFromModule(self.module)
789 return
790 if len(args) > 0:
791 self.testNames = args
792 else:
793 self.testNames = (self.defaultTest,)
794 self.createTests()
795 except getopt.error, msg:
796 self.usageExit(msg)
797
798 - def createTests(self):
799 self.test = self.testLoader.loadTestsFromNames(self.testNames,
800 self.module)
801
802 - def runTests(self):
803 if self.testRunner is None:
804 self.testRunner = TextTestRunner(verbosity=self.verbosity)
805 result = self.testRunner.run(self.test)
806 sys.exit(not result.wasSuccessful())
807
808 main = TestProgram
_
したがって、unittest.main()
を実行すると、768行目でself.runTests()
を呼び出すTestProgram
のオブジェクトが作成されます。コンストラクターは、テストを含むデフォルトモジュールとして現在のファイルも取得します。 (_module='__main__'
_)。 runTests()
が呼び出されると、次にself.testrunner.run()
が呼び出されます。 TextTestRunner
クラスの「run」メソッドを参照すると、実際に実行され、すべてのテスト結果が報告されることがわかります。テスト検出は、unittest.main()を呼び出すときに、行775の_TestProgram.parseArgs
_によって実行されます。 798行目の_self.createTests
_は、実際にはすべてのテストケースを検出し、テストスイートを作成する責任があります。これがすべての魔法です。
内部的には、unittest.main()
はいくつかのトリックを使用して、main()
の呼び出しを含むモジュール(ソースファイル)の名前を把握しています。
次に、このモジュールをインポートして調べ、テスト可能なすべてのクラスと関数のリストを取得し(構成に応じて)、それぞれのテストケースを作成します。
リストの準備ができると、各テストが順番に実行されます。