Index: build/android/pylib/instrumentation/test_runner_test.py |
diff --git a/build/android/pylib/instrumentation/test_runner_test.py b/build/android/pylib/instrumentation/test_runner_test.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..394c6b7c8b3130bf4ef3fdb2eec12bb99fc27034 |
--- /dev/null |
+++ b/build/android/pylib/instrumentation/test_runner_test.py |
@@ -0,0 +1,275 @@ |
+#!/usr/bin/env python |
+# Copyright 2014 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+ |
+"""Unit tests for instrumentation.TestRunner.""" |
+ |
+# pylint: disable=W0212 |
+ |
+import os |
+import sys |
+import unittest |
+ |
+from pylib import constants |
+from pylib.base import base_test_result |
+from pylib.instrumentation import test_runner |
+ |
+sys.path.append(os.path.join( |
+ constants.DIR_SOURCE_ROOT, 'third_party', 'pymock')) |
+import mock # pylint: disable=F0401 |
+ |
+ |
+class InstrumentationTestRunnerTest(unittest.TestCase): |
+ |
+ def setUp(self): |
+ options = mock.Mock() |
+ options.tool = '' |
+ package = mock.Mock() |
+ self.instance = test_runner.TestRunner(options, None, 0, package) |
+ |
+ def testParseAmInstrumentRawOutput_nothing(self): |
+ code, result, statuses = ( |
+ test_runner.TestRunner._ParseAmInstrumentRawOutput([''])) |
+ self.assertEqual(None, code) |
+ self.assertEqual([], result) |
+ self.assertEqual([], statuses) |
+ |
+ def testParseAmInstrumentRawOutput_noMatchingStarts(self): |
+ raw_output = [ |
+ '', |
+ 'this.is.a.test.package.TestClass:.', |
+ 'Test result for =.', |
+ 'Time: 1.234', |
+ '', |
+ 'OK (1 test)', |
+ ] |
+ |
+ code, result, statuses = ( |
+ test_runner.TestRunner._ParseAmInstrumentRawOutput(raw_output)) |
+ self.assertEqual(None, code) |
+ self.assertEqual([], result) |
+ self.assertEqual([], statuses) |
+ |
+ def testParseAmInstrumentRawOutput_resultAndCode(self): |
+ raw_output = [ |
+ 'INSTRUMENTATION_RESULT: foo', |
+ 'bar', |
+ 'INSTRUMENTATION_CODE: -1', |
+ ] |
+ |
+ code, result, _ = ( |
+ test_runner.TestRunner._ParseAmInstrumentRawOutput(raw_output)) |
+ self.assertEqual(-1, code) |
+ self.assertEqual(['foo', 'bar'], result) |
+ |
+ def testParseAmInstrumentRawOutput_oneStatus(self): |
+ raw_output = [ |
+ 'INSTRUMENTATION_STATUS: foo=1', |
+ 'INSTRUMENTATION_STATUS: bar=hello', |
+ 'INSTRUMENTATION_STATUS: world=false', |
+ 'INSTRUMENTATION_STATUS: class=this.is.a.test.package.TestClass', |
+ 'INSTRUMENTATION_STATUS: test=testMethod', |
+ 'INSTRUMENTATION_STATUS_CODE: 0', |
+ ] |
+ |
+ _, _, statuses = ( |
+ test_runner.TestRunner._ParseAmInstrumentRawOutput(raw_output)) |
+ |
+ expected = [ |
+ (0, { |
+ 'foo': ['1'], |
+ 'bar': ['hello'], |
+ 'world': ['false'], |
+ 'class': ['this.is.a.test.package.TestClass'], |
+ 'test': ['testMethod'], |
+ }) |
+ ] |
+ self.assertEqual(expected, statuses) |
+ |
+ def testParseAmInstrumentRawOutput_multiStatus(self): |
+ raw_output = [ |
+ 'INSTRUMENTATION_STATUS: class=foo', |
+ 'INSTRUMENTATION_STATUS: test=bar', |
+ 'INSTRUMENTATION_STATUS_CODE: 1', |
+ 'INSTRUMENTATION_STATUS: test_skipped=true', |
+ 'INSTRUMENTATION_STATUS_CODE: 0', |
+ 'INSTRUMENTATION_STATUS: class=hello', |
+ 'INSTRUMENTATION_STATUS: test=world', |
+ 'INSTRUMENTATION_STATUS: stack=', |
+ 'foo/bar.py (27)', |
+ 'hello/world.py (42)', |
+ 'test/file.py (1)', |
+ 'INSTRUMENTATION_STATUS_CODE: -1', |
+ ] |
+ |
+ _, _, statuses = ( |
+ test_runner.TestRunner._ParseAmInstrumentRawOutput(raw_output)) |
+ |
+ expected = [ |
+ (1, {'class': ['foo'], 'test': ['bar'],}), |
+ (0, {'test_skipped': ['true']}), |
+ (-1, { |
+ 'class': ['hello'], |
+ 'test': ['world'], |
+ 'stack': ['', 'foo/bar.py (27)', 'hello/world.py (42)', |
+ 'test/file.py (1)'], |
+ }), |
+ ] |
+ self.assertEqual(expected, statuses) |
+ |
+ def testParseAmInstrumentRawOutput_statusResultAndCode(self): |
+ raw_output = [ |
+ 'INSTRUMENTATION_STATUS: class=foo', |
+ 'INSTRUMENTATION_STATUS: test=bar', |
+ 'INSTRUMENTATION_STATUS_CODE: 1', |
+ 'INSTRUMENTATION_RESULT: hello', |
+ 'world', |
+ '', |
+ '', |
+ 'INSTRUMENTATION_CODE: 0', |
+ ] |
+ |
+ code, result, statuses = ( |
+ test_runner.TestRunner._ParseAmInstrumentRawOutput(raw_output)) |
+ |
+ self.assertEqual(0, code) |
+ self.assertEqual(['hello', 'world', '', ''], result) |
+ self.assertEqual([(1, {'class': ['foo'], 'test': ['bar']})], statuses) |
+ |
+ def testGenerateTestResult_noStatus(self): |
+ result = self.instance._GenerateTestResult( |
+ 'test.package.TestClass#testMethod', [], 0, 1000) |
+ self.assertEqual('test.package.TestClass#testMethod', result.GetName()) |
+ self.assertEqual(base_test_result.ResultType.UNKNOWN, result.GetType()) |
+ self.assertEqual('', result.GetLog()) |
+ self.assertEqual(1000, result.GetDur()) |
+ |
+ def testGenerateTestResult_testPassed(self): |
+ statuses = [ |
+ (1, { |
+ 'class': ['test.package.TestClass'], |
+ 'test': ['testMethod'], |
+ }), |
+ (0, { |
+ 'class': ['test.package.TestClass'], |
+ 'test': ['testMethod'], |
+ }), |
+ ] |
+ result = self.instance._GenerateTestResult( |
+ 'test.package.TestClass#testMethod', statuses, 0, 1000) |
+ self.assertEqual(base_test_result.ResultType.PASS, result.GetType()) |
+ |
+ def testGenerateTestResult_testSkipped_first(self): |
+ statuses = [ |
+ (0, { |
+ 'test_skipped': ['true'], |
+ }), |
+ (1, { |
+ 'class': ['test.package.TestClass'], |
+ 'test': ['testMethod'], |
+ }), |
+ (0, { |
+ 'class': ['test.package.TestClass'], |
+ 'test': ['testMethod'], |
+ }), |
+ ] |
+ result = self.instance._GenerateTestResult( |
+ 'test.package.TestClass#testMethod', statuses, 0, 1000) |
+ self.assertEqual(base_test_result.ResultType.SKIP, result.GetType()) |
+ |
+ def testGenerateTestResult_testSkipped_last(self): |
+ statuses = [ |
+ (1, { |
+ 'class': ['test.package.TestClass'], |
+ 'test': ['testMethod'], |
+ }), |
+ (0, { |
+ 'class': ['test.package.TestClass'], |
+ 'test': ['testMethod'], |
+ }), |
+ (0, { |
+ 'test_skipped': ['true'], |
+ }), |
+ ] |
+ result = self.instance._GenerateTestResult( |
+ 'test.package.TestClass#testMethod', statuses, 0, 1000) |
+ self.assertEqual(base_test_result.ResultType.SKIP, result.GetType()) |
+ |
+ def testGenerateTestResult_testSkipped_false(self): |
+ statuses = [ |
+ (0, { |
+ 'test_skipped': ['false'], |
+ }), |
+ (1, { |
+ 'class': ['test.package.TestClass'], |
+ 'test': ['testMethod'], |
+ }), |
+ (0, { |
+ 'class': ['test.package.TestClass'], |
+ 'test': ['testMethod'], |
+ }), |
+ ] |
+ result = self.instance._GenerateTestResult( |
+ 'test.package.TestClass#testMethod', statuses, 0, 1000) |
+ self.assertEqual(base_test_result.ResultType.PASS, result.GetType()) |
+ |
+ def testGenerateTestResult_testFailed(self): |
+ statuses = [ |
+ (1, { |
+ 'class': ['test.package.TestClass'], |
+ 'test': ['testMethod'], |
+ }), |
+ (-2, { |
+ 'class': ['test.package.TestClass'], |
+ 'test': ['testMethod'], |
+ }), |
+ ] |
+ result = self.instance._GenerateTestResult( |
+ 'test.package.TestClass#testMethod', statuses, 0, 1000) |
+ self.assertEqual(base_test_result.ResultType.FAIL, result.GetType()) |
+ |
+ def testGenerateTestResult_testCrashed(self): |
+ self.instance.test_pkg.GetPackageName = mock.Mock( |
+ return_value='generate.test.result.test.package') |
+ self.instance.device.old_interface.DismissCrashDialogIfNeeded = mock.Mock( |
+ return_value='generate.test.result.test.package') |
+ statuses = [ |
+ (1, { |
+ 'class': ['test.package.TestClass'], |
+ 'test': ['testMethod'], |
+ }), |
+ (-1, { |
+ 'class': ['test.package.TestClass'], |
+ 'test': ['testMethod'], |
+ 'stack': ['', 'foo/bar.py (27)', 'hello/world.py (42)'], |
+ }), |
+ ] |
+ result = self.instance._GenerateTestResult( |
+ 'test.package.TestClass#testMethod', statuses, 0, 1000) |
+ self.assertEqual(base_test_result.ResultType.CRASH, result.GetType()) |
+ self.assertEqual('\nfoo/bar.py (27)\nhello/world.py (42)', result.GetLog()) |
+ |
+ def testRunInstrumentationTest_verifyAdbShellCommand(self): |
+ self.instance.options.test_runner = 'MyTestRunner' |
+ self.instance.device.RunShellCommand = mock.Mock() |
+ self.instance._GenerateTestResult = mock.Mock() |
+ with mock.patch('pylib.instrumentation.test_runner.' |
+ 'TestRunner._ParseAmInstrumentRawOutput', |
+ return_value=(mock.Mock(), mock.Mock(), mock.Mock())): |
+ self.instance.RunInstrumentationTest( |
+ 'test.package.TestClass#testMethod', |
+ 'test.package', |
+ {'test_arg_key': 'test_arg_value'}, |
+ 100) |
+ self.instance.device.RunShellCommand.assert_called_with( |
+ ['am', 'instrument', '-r', |
+ '-e', 'test_arg_key', "'test_arg_value'", |
+ '-e', 'class', "'test.package.TestClass#testMethod'", |
+ '-w', 'test.package/MyTestRunner'], |
+ timeout=100, retries=0) |
+ |
+if __name__ == '__main__': |
+ unittest.main(verbosity=2) |
+ |