def test_sample_test_case(self): """ This test case is testing method function of ProductionClass. """ p_class = ProductionClass() resp = p_class.method('1') self.assertEqual(1, resp)
def test_get_status_obj_from_requests_params(self, call_type, st_code, r_object, resp_obj): r_object.get.return_value = resp_obj r_object.post.return_value = resp_obj resp_obj.status_code = st_code p_class = ProductionClass() resp = p_class.get_status_obj_from_requests(call_type) self.assertEqual(st_code, resp)
def test_resp_messages_new_auto_spec(self, g_api): p_class = ProductionClass() # case 1, 200: status_fun = MagicMock(return_value=200) g_api.status = status_fun g_api.status.return_value = 200 resp = p_class.get_url_status_message() self.assertEqual(resp, "UNKNOWN")
def test_google_resp_messages(self): """ This test is testing get_goolge_url_status_message function of ProductionClass.This function check the status of an URL and return cutomize message. """ p_class = ProductionClass() resp = p_class.get_goolge_url_status_message() self.assertTrue(resp != "ok", msg="Expected okk but got resp = {0}".format(resp))
def test_resp_messages(self): """ 此测试用例测试ProductionClass的get_url_status_message函数。 此函数检查URL的状态并返回格式消息。可帮助我们更好地了解测试用例失败的原因 """ p_class = ProductionClass() resp = p_class.get_url_status_message() # print(resp) print(resp != "ok") self.assertTrue(resp != "ok", msg="Expected ooo but got resp = {0}".format(resp))
def test_google_resp_messages_new_auto_spec_another_way(self): """ can also use autospec directly :return: """ p_class = ProductionClass() # case 1, 200: m_method = create_autospec(API.status, return_value=200) #g_api.status.return_value = 200 resp = p_class.get_goolge_url_status_message() self.assertEqual(resp, "ok")
def test_google_resp_messages_new_auto_spec(self, g_api): """ Patch in mock has 1 disadvantage that if there is a change in mocked function's parameters, tests will still pass but we would almost always want to catch passing incorrect parameters to any function we patch hence using `autospec` True gives this advantage, now this test will fail if `status` function's declaration changes in future :param g_api: mocked main.sample_api.API class """ p_class = ProductionClass() # case 1, 200: status_fun = MagicMock(return_value=200) g_api.status = status_fun g_api.status.return_value = 200 resp = p_class.get_goolge_url_status_message() self.assertEqual(resp, "UNKNOWN")
def test_get_status_obj_from_requests(self, r_object, resp_obj): r_object.get.return_value = resp_obj r_object.post.return_value = resp_obj resp_obj.status_code = 200 p_class = ProductionClass() resp_g = p_class.get_status_obj_from_requests("GET") self.assertEqual(200, resp_g) resp_obj.status_code = 405 resp_p = p_class.get_status_obj_from_requests("POST") self.assertEqual(405, resp_p) resp_p = p_class.get_status_obj_from_requests("NONE") self.assertEqual(404, resp_p)
def test_resp_messages_with_mock(self, g_api_method): """ 单元测试用例的目的应该是测试get_url_status_message方法的功能,而不是底层API。 在这个测试用例中,我们模拟了API类的'status'方法。 另外,为了测试所有场景,我们为这个模拟方法分配不同的返回值。 这样我们就不会进行实际的API调用,只是模仿它的行为。 """ p_class = ProductionClass() g_api_method.return_value = 200 # when `main.sample_api.API.status` will be called in this context, it will return 200 resp = p_class.get_url_status_message() self.assertEqual(resp, "ok") g_api_method.return_value = 302 # when `main.sample_api.API.status` will be called in this context, it will return 302 resp = p_class.get_url_status_message() self.assertEqual(resp, "redirection") g_api_method.return_value = 500 resp = p_class.get_url_status_message() self.assertEqual(resp, "Error") g_api_method.return_value = "Error" resp = p_class.get_url_status_message() self.assertEqual(resp, "Network") g_api_method.return_value = None resp = p_class.get_url_status_message() self.assertEqual(resp, "UNKNOWN")
def test_google_resp_messages_with_parameterised_and_mock( self, name, input_case, expected, g_api_method): """ Parameterized accept lists of iterables(list/tupple), it calls the same test case multiple times with value in each iterable as parameters. :param name: append `name` to current test case name. First value in iterable. :param input_case: input value against which we want to test. Second value in iterable. :param expected: expected respone for each test case. Third value in iterable. :param g_api_method: Mocked object of `main.sample_api.API.status` When we run this test case, it will run 5 times for 5 iterables. in each call values of `name`,`input_case` and `expected` will change. This test case serve the same purpose that of `test_google_resp_messages_with_mock` """ p_class = ProductionClass() g_api_method.return_value = input_case resp = p_class.get_goolge_url_status_message() self.assertEqual(resp, expected)
def test_get_status_obj_from_requests_side_effect(self, call_type, st_code, r_object, resp_obj): """ When you cover almost everything in code using mock, you generally remains with "how do I cover the exceptions" `side_effect` is 1 of the simplest answer to it. in this test, we are intentionally adding `AttributeError` in side_effect property of the mocked function which simulates the exact behaviour of exception raise in production and so it covers the exception block of your code as well. :param call_type: call type is input to underlying function we are testing :param st_code: status code to mock with :param r_object: mock request object :param resp_obj: mock response object Also note here, while using multiple patch, the decorators are applied bottom-up and the order of the parameters need to match this. Why: this is how python makes the order of execution for this test: main.sample_api.requests.Response(main.sample_api.requests(test_get_status_obj_from_requests_side_effect)) and hence parameters order should be carefully written (bottom-up/reverse of patch) """ r_object.get.return_value = resp_obj r_object.post.return_value = resp_obj resp_obj.status_code = st_code p_class = ProductionClass() resp = p_class.get_status_obj_from_requests_side_effect(call_type) self.assertEqual(st_code, resp) r_object.get.side_effect = AttributeError() r_object.post.side_effect = AttributeError() p_class = ProductionClass() resp = p_class.get_status_obj_from_requests_side_effect(call_type) self.assertEqual(404, resp)
def test_google_resp_messages_with_mock(self, g_api_method): """ Above test case `test_google_resp_messages` simply call the function and return the cutom message by actually invoking the API call to the URL. However purpose of the unit test case should be to test the functionality of get_goolge_url_status_message method, not the underlying API. In this test case, we mock the `status` method of API class. Also to test all scenarios, we assign different return value to this mocked method. This way we don't make the actual API call, but just mock it's behaviour. `When to use Mock` - Any method which is making API call, DB call or any other external dependency. @params -`g_api_method` : Mocked instance of `main.sample_api.API.status` """ p_class = ProductionClass() g_api_method.return_value = 200 # when `main.sample_api.API.status` will be called in this context, it will return 200 resp = p_class.get_goolge_url_status_message() self.assertEqual(resp, "ok") g_api_method.return_value = 302 # when `main.sample_api.API.status` will be called in this context, it will return 302 resp = p_class.get_goolge_url_status_message() self.assertEqual(resp, "redirection") g_api_method.return_value = 500 resp = p_class.get_goolge_url_status_message() self.assertEqual(resp, "Error") g_api_method.return_value = "Error" resp = p_class.get_goolge_url_status_message() self.assertEqual(resp, "Network") g_api_method.return_value = None resp = p_class.get_goolge_url_status_message() self.assertEqual(resp, "UNKNOWN")
def test_get_status_obj_from_requests_side_effect(self, call_type, st_code, r_object, resp_obj): """ 在这个测试中,我们故意在mocked函数的side_effect属性中添加`AttributeError`, 它模拟生产中异常引发的确切行为,因此它也涵盖了代码的异常块。 """ r_object.get.return_value = resp_obj r_object.post.return_value = resp_obj resp_obj.status_code = st_code p_class = ProductionClass() resp = p_class.get_status_obj_from_requests_side_effect(call_type) self.assertEqual(st_code, resp) r_object.get.side_effect = AttributeError() r_object.post.side_effect = AttributeError() p_class = ProductionClass() resp = p_class.get_status_obj_from_requests_side_effect(call_type) self.assertEqual(404, resp)
def test_resp_messages_with_parameterised_and_mock(self, name, input_case, expected, g_api_method): p_class = ProductionClass() g_api_method.return_value = input_case resp = p_class.get_url_status_message() self.assertEqual(resp, expected)
def test_sample_test_case(self): p_class = ProductionClass() resp = p_class.method('1') self.assertEqual(1, resp)