summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAng Li <angli@google.com>2016-02-12 23:54:59 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-02-12 23:54:59 +0000
commitc1fd1fe8830be08faef1da4b6925f762be5be49d (patch)
treecc60a04d9f31d57fd9235a6a4219478b135334d3
parent32ab46578ae1e3528df05f3eef19f2646bf28d33 (diff)
parent5467eb01af53b7294a1c03cf59f7a07531426970 (diff)
downloadplatform_tools_test_connectivity-c1fd1fe8830be08faef1da4b6925f762be5be49d.tar.gz
platform_tools_test_connectivity-c1fd1fe8830be08faef1da4b6925f762be5be49d.tar.bz2
platform_tools_test_connectivity-c1fd1fe8830be08faef1da4b6925f762be5be49d.zip
Merge "Refactor unit tests for acts.base_test." into mm-wireless-dev
am: 5467eb01af * commit '5467eb01af53b7294a1c03cf59f7a07531426970': Refactor unit tests for acts.base_test.
-rw-r--r--acts/framework/tests/ActsSanityTestGroup.txt2
-rw-r--r--acts/framework/tests/BaseTestClassTests/ActsBaseClassSetupClassTest.py41
-rw-r--r--acts/framework/tests/BaseTestClassTests/ActsBaseClassTest.py383
-rwxr-xr-xacts/framework/tests/acts_base_class_test.py338
-rwxr-xr-xacts/framework/tests/test_acts2
5 files changed, 340 insertions, 426 deletions
diff --git a/acts/framework/tests/ActsSanityTestGroup.txt b/acts/framework/tests/ActsSanityTestGroup.txt
index 78deb8265e..23dad0c98e 100644
--- a/acts/framework/tests/ActsSanityTestGroup.txt
+++ b/acts/framework/tests/ActsSanityTestGroup.txt
@@ -1,4 +1,2 @@
-ActsBaseClassTest
-ActsBaseClassSetupClassTest
ActsRecordsTest
ActsAndroidDeviceTest \ No newline at end of file
diff --git a/acts/framework/tests/BaseTestClassTests/ActsBaseClassSetupClassTest.py b/acts/framework/tests/BaseTestClassTests/ActsBaseClassSetupClassTest.py
deleted file mode 100644
index e18bc27e82..0000000000
--- a/acts/framework/tests/BaseTestClassTests/ActsBaseClassSetupClassTest.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/python3.4
-#
-# Copyright 2015 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import json
-import os
-
-from acts.base_test import BaseTestClass
-
-class ActsBaseClassSetupClassTest(BaseTestClass):
- """This class tests aborting test class by causing a failure in
- setup_class.
-
- When implementation is correct, no test case in this class should be
- executed.
- """
-
- def __init__(self, controllers):
- BaseTestClass.__init__(self, controllers)
- self.tests = (
- "test_never",
- )
-
- def setup_class(self):
- self.fail("Fail setup_class to abort this test", extras=42)
-
- def test_never(self):
- self.log.error("This test should never happen.")
- self.assert_true(False, "BAD!!")
diff --git a/acts/framework/tests/BaseTestClassTests/ActsBaseClassTest.py b/acts/framework/tests/BaseTestClassTests/ActsBaseClassTest.py
deleted file mode 100644
index 5d14c3d720..0000000000
--- a/acts/framework/tests/BaseTestClassTests/ActsBaseClassTest.py
+++ /dev/null
@@ -1,383 +0,0 @@
-#!/usr/bin/env python3.4
-#
-# Copyright 2016 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from acts.base_test import BaseTestClass
-from acts.base_test import BaseTestError
-from acts.signals import generated_test
-from acts.signals import TestSignal
-from acts.signals import TestSignalError
-
-class Something:
- """Empty class used to test json serialization check."""
-
-class ActsBaseClassTest(BaseTestClass):
- """This test class tests the implementation of BaseTestClass.
-
- Including:
- - Different ways to mark the result of a test case.
- - Test case name convention enforcement
- - None existent test case handling.
- """
- EXTRA_ARG = "An extra arg"
-
- def __init__(self, controllers):
- BaseTestClass.__init__(self, controllers)
- self.tests = (
- "test_none_existent",
- "invalid_test_name",
- "test_current_test_case_name",
- "test_setup_test_fail_by_exception",
- "test_setup_test_fail_by_test_signal",
- "test_setup_test_fail_by_return_False",
- "test_uncaught_exception",
- "test_return_True",
- "test_implicit_pass",
- "test_return_False",
- "test_fail",
- "test_fail_with_int_extra",
- "test_explicit_pass",
- "test_explicit_pass_with_str_extra",
- "test_assert_true",
- "test_assert_true_with_extras",
- "test_skip",
- "test_skip_with_extras",
- "test_skip_if",
- "test_generated_test_with_kwargs",
- # WARNING: the last test in test_generated_tests is abort_class.
- # Any test after this line will never be run!
- "test_generated_tests",
- "test_never"
- )
-
- def setup_class(self):
- self.log.info("In setup_class.")
-
- def setup_test(self):
- """Make sure empty setup_test does not block.
- """
- if "setup_test_fail_by_exception" in self.current_test_name:
- raise Exception("Expected failure because setup_test failed by "
- "uncaught exception.")
- elif "setup_test_fail_by_test_signal" in self.current_test_name:
- self.fail("Excepted failure because setup_test failed by test "
- "signal.")
- elif "setup_test_fail_by_return_False" in self.current_test_name:
- return False
-
- def on_pass(self, test_name, begin_time):
- self.log.info("In on_pass.")
- msg = "%s should not have passed." % test_name
- expected_success = (
- "test_return_True",
- "test_generated_return_True",
- "test_generated_tests",
- "test_implicit_pass",
- "test_explicit_pass_with_str_extra",
- "test_generated_implicit_pass",
- "test_generated_explicit_pass_with_str_extra",
- "test_test_args",
- "test_explicit_pass",
- "test_unpack_userparams_required",
- "test_unpack_userparams_optional",
- "test_unpack_userparams_default",
- "test_unpack_userparams_default_overwrite",
- "test_unpack_userparams_default_None",
- "test_generated_explicit_pass",
- "test_invalid_signal_details",
- "test_invalid_signal_extras",
- "test_generated_test_with_kwargs_case",
- "test_current_test_case_name"
- )
- self.assert_true(test_name in expected_success, msg)
-
- def on_fail(self, test_name, begin_time):
- self.log.info("In on_fail.")
- if test_name == "test_assert_true":
- msg = ("Raising an exception to make sure exceptions in procedure "
- "functions don't crash the test framework.")
- self.log.info(msg)
- raise Exception("Excepted exception.")
-
- def on_skip(self, test_name, begin_time):
- self.log.info("In on_skip")
- msg = "%s should not have been skipped." % test_name
- expected_skip = (
- "test_skip",
- "test_skip_with_extras",
- "test_skip_if",
- "test_generated_skip",
- "test_generated_skip_if",
- "test_generated_skip_with_extras",
- "test_unsolicited_test_args",
- "test_explicit_test_args_skip"
- )
- self.assert_true(test_name in expected_skip, msg)
-
- def on_exception(self, test_name, begin_time):
- self.log.info("In on_exception")
- msg = "%s should not have thrown exception." % test_name
- expected_exception = (
- "test_uncaught_exception",
- "test_generated_uncaught_exception",
- "test_setup_test_fail_by_exception",
- "test_generated_setup_test_fail_by_exception"
- )
- self.assert_true(test_name in expected_exception, msg)
-
- def generated_test_logic(self, param, extra_arg):
- """Execute all the test_ functions in the generated test case.
-
- Args:
- param: The partial name of the test function to executed.
- extra_arg: An extra arg added to make sure passing extra args work.
- """
- self.log.info("This is a generated test case with param %s" % param)
- self.assert_true(extra_arg == self.EXTRA_ARG,
- "Wrong extra arg %s" % extra_arg)
- # In case we want to add more fields to param, using a local var here.
- t = param
- test_func = getattr(self, "test_%s" % t)
- return test_func()
-
- def name_gen(self, param, extra_arg):
- return "test_generated_%s" % param
-
- """ Begin of Tests """
-
- def invalid_test_name(self):
- raise Exception("This should never be executed!")
-
- def test_current_test_case_name(self):
- my_name = "test_current_test_case_name"
- self.assert_true(self.current_test_name == my_name,
- "Expected current_test_name to be %s, got %s" % (
- my_name, self.current_test_name))
-
- def test_setup_test_fail_by_exception(self):
- self.fail("This line should not have been executed!")
-
- def test_setup_test_fail_by_test_signal(self):
- self.fail("This line should not have been executed!")
-
- def test_setup_test_fail_by_return_False(self):
- self.fail("This line should not have been executed!")
-
-
- def test_uncaught_exception(self):
- raise Exception("This should fail because of uncaught exception.")
-
- def test_return_True(self):
- self.log.info("This should pass because return True.")
- return True
-
- def test_implicit_pass(self):
- self.log.info("This should pass because no error happened.")
-
- def test_return_False(self):
- self.log.info("This should fail because returned False.")
- return False
-
- def test_fail(self):
- self.fail("Expected failure with explicit fail.")
-
- def test_explicit_pass(self):
- self.explicit_pass("Expected pass with explicit pass.")
-
- def test_explicit_pass_with_str_extra(self):
- self.explicit_pass("Should fail because asserting True on False.",
- extras="This is a string extra.")
-
- def test_assert_true(self):
- self.assert_true(False, "Should fail because asserting True on False.")
-
- def test_assert_true_with_extras(self):
- self.assert_true(False, "Should fail because asserting True on False.",
- extras={
- "what is this": "An extra!",
- "what happened": "I failed!",
- "cause_code": "haha"
- })
-
- def test_fail_with_int_extra(self):
- self.fail("Should fail because asserting True on False.", extras=0)
-
- def test_skip(self):
- self.skip("Expected skip.")
-
- def test_skip_with_extras(self):
- self.skip("Expected skip.",
- extras={
- "what is this": "An extra!",
- "what happened": "I skipped!",
- "cause_code": "haha"
- })
-
- def test_skip_if(self):
- self.skip_if(True, "Expected skip.")
-
- def test_abort_class(self):
- self.abort_class("Expected abortion of this test class.")
-
- def test_abort_class_if(self):
- self.abort_class_if(True, "This is expected to abort this test class.")
-
- def test_abort_all(self):
- self.abort_all("This is expected to abort all remaining tests.")
-
- def test_abort_all_if(self):
- msg = "This is expected to abort all remaining tests."
- self.abort_all_if(True, msg)
-
- def test_never(self):
- self.log.error("This test should never happen.")
- self.assert_true(False, "BAD!!")
-
- def test_test_args(self, *args):
- self.log.info("Got cli args: {}".format(args))
- self.assert_true(args, ("You should specify at least one arg with "
- "--test_args for this test."))
-
- def test_explicit_test_args_skip(self, one_arg):
- self.log.error("Got cli arg: {}. This test should have been skipped. "
- "You should either specify more than one for --test_args, or no "
- "--test_args at all.".format(one_arg))
- self.assert_true(False, "BAD!!")
-
- def test_unpack_userparams_required(self):
- required_param = "something"
- required = [required_param]
- try:
- self.unpack_userparams(required)
- except BaseTestError:
- self.explicit_pass("Got expected exception caused by missing "
- "required param.")
- self.fail(("Required param '%s' missing, unpack funtion should have "
- "raised exception.") % required_param)
-
- def test_unpack_userparams_optional(self):
- optional_param = "something"
- opt = [optional_param]
- self.unpack_userparams(opt_param_names=opt)
-
- def test_unpack_userparams_default(self):
- arg = "haha"
- self.unpack_userparams(arg1=arg)
- self.assert_true(self.arg1 == arg,
- ("Expected to have self.arg1 set to %s on the test "
- "class, got %s") % (arg, self.arg1))
-
- def test_unpack_userparams_default_overwrite(self):
- default_arg_val = "haha"
- actual_arg_val = "wawa"
- arg_name = "arg1"
- self.user_params[arg_name] = actual_arg_val
- self.unpack_userparams(opt_param_names=[arg_name],
- arg1=default_arg_val)
- self.assert_true(self.arg1 == actual_arg_val,
- ("Expected to have self.arg1 set to %s on the test "
- "class, got %s") % (actual_arg_val, self.arg1))
-
- def test_unpack_userparams_default_None(self):
- self.unpack_userparams(arg1=None)
- self.assert_true(self.arg1 is None,
- ("Expected to have self.arg1 set to None on the test "
- "class, got %s") % self.arg1)
-
- def test_unsolicited_test_args(self):
- self.log.error("This test should have been skipped. Did you run with "
- "--test_args specified?")
- self.assert_true(False, "BAD!!")
-
- def test_invalid_signal_details(self):
- sth = Something()
- try:
- TestSignal(sth)
- except TestSignalError:
- self.explicit_pass("Got expected exception TestSignalError.")
- self.fail("This line should not have executed.")
-
- def test_invalid_signal_extras(self):
- sth = Something()
- try:
- TestSignal("test", extras=sth)
- except TestSignalError:
- self.explicit_pass("Got expected exception TestSignalError.")
- self.fail("This line should not have executed.")
-
- @generated_test
- def test_generated_tests(self):
- params = [
- "return_False",
- "setup_test_fail_by_exception",
- "setup_test_fail_by_test_signal",
- "setup_test_fail_by_return_False",
- "assert_true",
- "assert_true_with_extras",
- "implicit_pass",
- "explicit_pass",
- "explicit_pass_with_str_extra",
- "fail",
- "fail_with_int_extra",
- "skip",
- "skip_with_extras",
- "skip_if",
- "uncaught_exception",
- "abort_class",
- "never"
- ]
- failed = self.run_generated_testcases(
- self.generated_test_logic,
- params, args=(self.EXTRA_ARG,),
- name_func=self.name_gen)
-
- @generated_test
- def test_generated_test_with_kwargs(self):
- kwarg1_name = "kwarg_1"
- kwarg1_val = "whatever"
- kwarg2_name = "kwarg_2"
- kwarg2_val = "whateverAgain"
- param = "I'm a param."
- def func(p, extra, **kwargs):
- self.assert_true(p == param, ("Expected to get param '%s', got "
- "'%s'") % (param, p))
- self.assert_true(kwarg1_name in kwargs,
- "Missing expected kwarg %s." % kwarg1_name)
- self.assert_true(kwargs[kwarg1_name] == kwarg1_val,
- "Expected %s to be %s, got %s" % (
- kwarg1_name,
- kwarg1_val,
- kwargs[kwarg1_name]))
- self.assert_true(kwarg2_name in kwargs,
- "Missing expected kwarg %s." % kwarg2_name)
- self.assert_true(kwargs[kwarg2_name] == kwarg2_val,
- "Expected %s to be %s, got %s" % (
- kwarg2_name,
- kwarg2_val,
- kwargs[kwarg2_name]))
- self.log.info(("Got expected param '%s', arg '%s', and kwarg '%s'."
- ) % (p, extra, kwargs))
- def name_func(p, extra, **kwargs):
- func(p, extra, **kwargs)
- return "test_generated_test_with_kwargs_case"
- self.run_generated_testcases(
- func,
- [param],
- kwargs={"kwarg_2": kwarg2_val,
- "extra": self.EXTRA_ARG,
- "kwarg_1": kwarg1_val},
- name_func=name_func)
-
- """ End of Tests """
diff --git a/acts/framework/tests/acts_base_class_test.py b/acts/framework/tests/acts_base_class_test.py
new file mode 100755
index 0000000000..55d523e738
--- /dev/null
+++ b/acts/framework/tests/acts_base_class_test.py
@@ -0,0 +1,338 @@
+#!/usr/bin/env python3.4
+#
+# Copyright 2016 - The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+try:
+ from unittest import mock # PY3
+except ImportError:
+ import mock # PY2
+
+import unittest
+
+from acts import base_test
+from acts import signals
+
+MSG_EXPECTED_EXCEPTION = "This is an expected exception."
+MSG_EXPECTED_TEST_FAILURE = "This is an expected test failure."
+MSG_UNEXPECTED_EXCEPTION = "Unexpected exception!"
+
+MOCK_EXTRA = {"key": "value", "answer_to_everything": 42}
+
+def never_call():
+ raise Exception(MSG_UNEXPECTED_EXCEPTION)
+
+class ActsBaseClassTest(unittest.TestCase):
+
+ def setUp(self):
+ self.mock_test_cls_configs = {
+ 'reporter': mock.MagicMock(),
+ 'log': mock.MagicMock(),
+ 'log_path': '/tmp',
+ 'cli_args': None,
+ 'user_params': {}
+ }
+ self.mock_test_name = "test_something"
+
+ def test_current_test_case_name(self):
+ class MockBaseTest(base_test.BaseTestClass):
+ def test_func(self):
+ self.assert_true(self.current_test_name == "test_func", ("Got "
+ "unexpected test name %s."
+ ) % self.current_test_name)
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_func"])
+ actual_record = bt_cls.results.passed[0]
+ self.assertEqual(actual_record.test_name, "test_func")
+ self.assertIsNone(actual_record.details)
+ self.assertIsNone(actual_record.extras)
+
+ def test_setup_class_fail_by_exception(self):
+ class MockBaseTest(base_test.BaseTestClass):
+ def setup_class(self):
+ raise Exception(MSG_EXPECTED_EXCEPTION)
+ def test_something(self):
+ # This should not execute because setup_class failed.
+ never_call()
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_func"])
+ actual_record = bt_cls.results.failed[0]
+ self.assertEqual(actual_record.test_name, "")
+ expected_msg = "setup_class failed for MockBaseTest: %s" % (
+ MSG_EXPECTED_EXCEPTION)
+ self.assertEqual(actual_record.details, expected_msg)
+ self.assertIsNone(actual_record.extras)
+ expected_summary = ("Executed 1, Failed 1, Passed 0, Requested 1, "
+ "Skipped 0, Unknown 0")
+ self.assertEqual(bt_cls.results.summary_str(), expected_summary)
+
+ def test_setup_test_fail_by_exception(self):
+ class MockBaseTest(base_test.BaseTestClass):
+ def setup_test(self):
+ raise Exception(MSG_EXPECTED_EXCEPTION)
+ def test_something(self):
+ # This should not execute because setup_test failed.
+ never_call()
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_something"])
+ actual_record = bt_cls.results.unknown[0]
+ self.assertEqual(actual_record.test_name, self.mock_test_name)
+ self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
+ self.assertIsNone(actual_record.extras)
+ expected_summary = ("Executed 1, Failed 0, Passed 0, Requested 1, "
+ "Skipped 0, Unknown 1")
+ self.assertEqual(bt_cls.results.summary_str(), expected_summary)
+
+ def test_setup_test_fail_by_test_signal(self):
+ class MockBaseTest(base_test.BaseTestClass):
+ def setup_test(self):
+ raise signals.TestFailure(MSG_EXPECTED_EXCEPTION)
+ def test_something(self):
+ # This should not execute because setup_test failed.
+ never_call()
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_something"])
+ actual_record = bt_cls.results.failed[0]
+ self.assertEqual(actual_record.test_name, self.mock_test_name)
+ self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
+ self.assertIsNone(actual_record.extras)
+ expected_summary = ("Executed 1, Failed 1, Passed 0, Requested 1, "
+ "Skipped 0, Unknown 0")
+ self.assertEqual(bt_cls.results.summary_str(), expected_summary)
+
+ def test_setup_test_fail_by_return_False(self):
+ class MockBaseTest(base_test.BaseTestClass):
+ def setup_test(self):
+ return False
+ def test_something(self):
+ # This should not execute because setup_test failed.
+ never_call()
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_something"])
+ actual_record = bt_cls.results.failed[0]
+ expected_msg = "Setup for %s failed." % self.mock_test_name
+ self.assertEqual(actual_record.test_name, self.mock_test_name)
+ self.assertEqual(actual_record.details, expected_msg)
+ self.assertIsNone(actual_record.extras, None)
+ expected_summary = ("Executed 1, Failed 1, Passed 0, Requested 1, "
+ "Skipped 0, Unknown 0")
+ self.assertEqual(bt_cls.results.summary_str(), expected_summary)
+
+ def test_abort_class(self):
+ class MockBaseTest(base_test.BaseTestClass):
+ def test_1(self):
+ pass
+ def test_2(self):
+ self.abort_class(MSG_EXPECTED_EXCEPTION)
+ never_call()
+ def test_3(self):
+ never_call()
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_1", "test_2", "test_3"])
+ self.assertEqual(bt_cls.results.passed[0].test_name,
+ "test_1")
+ self.assertEqual(bt_cls.results.skipped[0].details,
+ MSG_EXPECTED_EXCEPTION)
+ self.assertEqual(bt_cls.results.summary_str(),
+ ("Executed 2, Failed 0, Passed 1, Requested 3, "
+ "Skipped 1, Unknown 0"))
+
+ def test_uncaught_exception(self):
+ class MockBaseTest(base_test.BaseTestClass):
+ def test_func(self):
+ raise Exception(MSG_EXPECTED_EXCEPTION)
+ never_call()
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_func"])
+ actual_record = bt_cls.results.unknown[0]
+ self.assertEqual(actual_record.test_name, "test_func")
+ self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
+ self.assertIsNone(actual_record.extras)
+
+ def test_fail(self):
+ class MockBaseTest(base_test.BaseTestClass):
+ def test_func(self):
+ self.fail(MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
+ never_call()
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_func"])
+ actual_record = bt_cls.results.failed[0]
+ self.assertEqual(actual_record.test_name, "test_func")
+ self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
+ self.assertEqual(actual_record.extras, MOCK_EXTRA)
+
+ def test_assert_true(self):
+ class MockBaseTest(base_test.BaseTestClass):
+ def test_func(self):
+ self.assert_true(False, MSG_EXPECTED_EXCEPTION,
+ extras=MOCK_EXTRA)
+ never_call()
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_func"])
+ actual_record = bt_cls.results.failed[0]
+ self.assertEqual(actual_record.test_name, "test_func")
+ self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
+ self.assertEqual(actual_record.extras, MOCK_EXTRA)
+
+ def test_explicit_pass(self):
+ class MockBaseTest(base_test.BaseTestClass):
+ def test_func(self):
+ self.explicit_pass(MSG_EXPECTED_EXCEPTION,
+ extras=MOCK_EXTRA)
+ never_call()
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_func"])
+ actual_record = bt_cls.results.passed[0]
+ self.assertEqual(actual_record.test_name, "test_func")
+ self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
+ self.assertEqual(actual_record.extras, MOCK_EXTRA)
+
+ def test_implicit_pass(self):
+ class MockBaseTest(base_test.BaseTestClass):
+ def test_func(self):
+ pass
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_func"])
+ actual_record = bt_cls.results.passed[0]
+ self.assertEqual(actual_record.test_name, "test_func")
+ self.assertIsNone(actual_record.details)
+ self.assertIsNone(actual_record.extras)
+
+ def test_skip(self):
+ class MockBaseTest(base_test.BaseTestClass):
+ def test_func(self):
+ self.skip(MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
+ never_call()
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_func"])
+ actual_record = bt_cls.results.skipped[0]
+ self.assertEqual(actual_record.test_name, "test_func")
+ self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
+ self.assertEqual(actual_record.extras, MOCK_EXTRA)
+
+ def test_skip_if(self):
+ class MockBaseTest(base_test.BaseTestClass):
+ def test_func(self):
+ self.skip_if(False, MSG_UNEXPECTED_EXCEPTION)
+ self.skip_if(True, MSG_EXPECTED_EXCEPTION,
+ extras=MOCK_EXTRA)
+ never_call()
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_func"])
+ actual_record = bt_cls.results.skipped[0]
+ self.assertEqual(actual_record.test_name, "test_func")
+ self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
+ self.assertEqual(actual_record.extras, MOCK_EXTRA)
+
+ def test_unpack_userparams_required(self):
+ """Missing a required param should raise an error."""
+ required = ["something"]
+ bc = base_test.BaseTestClass(self.mock_test_cls_configs)
+ expected_msg = ("Missing required user param '%s' in test "
+ "configuration.") % required[0]
+ with self.assertRaises(base_test.BaseTestError, msg=expected_msg):
+ bc.unpack_userparams(required)
+
+ def test_unpack_userparams_optional(self):
+ """Missing an optional param should not raise an error."""
+ opt = ["something"]
+ bc = base_test.BaseTestClass(self.mock_test_cls_configs)
+ bc.unpack_userparams(opt_param_names=opt)
+
+ def test_unpack_userparams_basic(self):
+ """Required and optional params are unpacked properly."""
+ required = ["something"]
+ optional = ["something_else"]
+ configs = dict(self.mock_test_cls_configs)
+ configs["user_params"]["something"] = 42
+ configs["user_params"]["something_else"] = 53
+ bc = base_test.BaseTestClass(configs)
+ bc.unpack_userparams(req_param_names=required,
+ opt_param_names=optional)
+ self.assertEqual(bc.something, 42)
+ self.assertEqual(bc.something_else, 53)
+
+ def test_unpack_userparams_default_overwrite(self):
+ default_arg_val = "haha"
+ actual_arg_val = "wawa"
+ arg_name = "arg1"
+ configs = dict(self.mock_test_cls_configs)
+ configs["user_params"][arg_name] = actual_arg_val
+ bc = base_test.BaseTestClass(configs)
+ bc.unpack_userparams(opt_param_names=[arg_name],
+ arg1=default_arg_val)
+ self.assertEqual(bc.arg1, actual_arg_val)
+
+ def test_unpack_userparams_default_None(self):
+ bc = base_test.BaseTestClass(self.mock_test_cls_configs)
+ bc.unpack_userparams(arg1="haha")
+ self.assertEqual(bc.arg1, "haha")
+
+ def test_generated_tests(self):
+ """Execute code paths for generated test cases.
+
+ Three test cases are generated, each of them produces a different
+ result: one pass, one fail, and one skip.
+
+ This test verifies that the exact three tests are executed and their
+ results are reported correctly.
+ """
+ static_arg = "haha"
+ static_kwarg = "meh"
+ itrs = ["pass", "fail", "skip"]
+ class MockBaseTest(base_test.BaseTestClass):
+ def name_gen(self, setting, arg, special_arg=None):
+ return "test_%s_%s" % (setting, arg)
+ def logic(self, setting, arg, special_arg=None):
+ self.assert_true(setting in itrs,
+ ("%s is not in acceptable settings range %s"
+ ) % (setting, itrs))
+ self.assert_true(arg == static_arg,
+ "Expected %s, got %s" % (static_arg, arg))
+ self.assert_true(arg == static_arg,
+ "Expected %s, got %s" % (static_kwarg,
+ special_arg))
+ if setting == "pass":
+ self.explicit_pass(MSG_EXPECTED_EXCEPTION,
+ extras=MOCK_EXTRA)
+ elif setting == "fail":
+ self.fail(MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
+ elif setting == "skip":
+ self.skip(MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
+ @signals.generated_test
+ def test_func(self):
+ self.run_generated_testcases(
+ test_func=self.logic,
+ settings=itrs,
+ args=(static_arg,),
+ name_func=self.name_gen
+ )
+ bt_cls = MockBaseTest(self.mock_test_cls_configs)
+ bt_cls.run(test_names=["test_func"])
+ self.assertEqual(len(bt_cls.results.requested), 3)
+ pass_record = bt_cls.results.passed[0]
+ self.assertEqual(pass_record.test_name, "test_pass_%s" % static_arg)
+ self.assertEqual(pass_record.details, MSG_EXPECTED_EXCEPTION)
+ self.assertEqual(pass_record.extras, MOCK_EXTRA)
+ skip_record = bt_cls.results.skipped[0]
+ self.assertEqual(skip_record.test_name, "test_skip_%s" % static_arg)
+ self.assertEqual(skip_record.details, MSG_EXPECTED_EXCEPTION)
+ self.assertEqual(skip_record.extras, MOCK_EXTRA)
+ fail_record = bt_cls.results.failed[0]
+ self.assertEqual(fail_record.test_name, "test_fail_%s" % static_arg)
+ self.assertEqual(fail_record.details, MSG_EXPECTED_EXCEPTION)
+ self.assertEqual(fail_record.extras, MOCK_EXTRA)
+
+if __name__ == "__main__":
+ unittest.main() \ No newline at end of file
diff --git a/acts/framework/tests/test_acts b/acts/framework/tests/test_acts
index 8c27f0315d..8540a04bf4 100755
--- a/acts/framework/tests/test_acts
+++ b/acts/framework/tests/test_acts
@@ -4,3 +4,5 @@ import subprocess
cmd = "act.py -c acts_sanity_test_config.json -tf ActsSanityTestGroup.txt"
subprocess.check_call([cmd], shell=True)
+cmd = "python3 acts_base_class_test.py"
+subprocess.check_call([cmd], shell=True)