Foreword:
Interface automation refers to the automation at the interface level of the simulation program. Because the interface is not easy to change and the maintenance cost is lower, it is deeply loved by major companies.
Interface automation includes two parts, functional interface automation testing and concurrent interface automation testing.
This article focuses on the first, functional interface automation framework.
1. Brief introduction
Environment: Mac, Python 3, Pytest, Allure, Request
Process: Read Yaml test data – generate test cases – execute test cases – generate Allure report
Design instructions for module classes:
Request.py
encapsulates the request method and can support multi-protocol extensions (get\post\put)
Config.py
Read configuration files, including: configurations for different environments, email-related configurations
Log.py
encapsulates the log method, which is divided into: debug, info, warning, error, critical
Email.py
encapsulates the smtplib method and sends email notifications of the running results.
Assert.py
encapsulates the assert method
run.py
core code. Define and execute use case sets and generate reports
Yaml test data format is as follows:
--- Basic: dec: "Basic settings" parameters: - url: /settings/basic.json data: slug=da1677475c27 header: { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko)\ Chrome/67.0.3396.99 Safari/537.36", "Content-Type": "keep-alive" }
2. Code structure and framework process
1. The code structure is shown in the figure below:
2. The framework process is shown in the figure below:
3. Detailed functions and usage instructions
1. Define the configuration file config.ini
This file distinguishes between the test environment [private_debug] and the formal environment [online_release] and defines related configuration items respectively. The [mail] part is the mail-related configuration items.
# http interface test framework configuration information [private_debug] # debug test service tester=your name environment=debug versionCode = your version host=www.jianshu.com loginHost = /Login loginInfo = [email protected] & amp;password=123456 [online_release] # release official service tester=your name environment=release versionCode = v1.0 host=www.jianshu.com loginHost = /Login loginInfo = [email protected] & amp;password=123456 [mail] #Send email message smtpserver = smtp.163.com sender = [email protected] receiver = [email protected] username = [email protected] password = 123456
2. Read the yaml test data and encapsulate it
See the first section for an example of yaml test data. An interface can define multiple case data. get_parameter is an encapsulated method for reading yaml data. After reading in a loop, multiple case data will be stored in the list.
class Basic: params = get_parameter('Basic') url = [] data = [] header = [] for i in range(0, len(params)): url.append(params[i]['url']) data.append(params[i]['data']) header.append(params[i]['header'])
3. Write use cases
class TestBasic: @pytest.allure.feature('Home') @allure.severity('blocker') @allure.story('Basic') def test_basic_01(self, action): """ Use case description: View basic settings without logging in """ conf = Config() data = Basic() test = Assert.Assertions() request = Request.Request(action) host = conf.host_debug req_url = 'http://' + host urls = data.url params = data.data headers = data.header api_url = req_url + urls[0] response = request.get_request(api_url, params[0], headers[0]) assert test.assert_code(response['code'], 401) assert test.assert_body(response['body'], 'error', u'Please register or log in before continuing.') assert test.assert_time(response['time_consuming'], 400) Consts.RESULT_LIST.append('True')
4. Run the entire framework run.py
if __name__ == '__main__': # Define test set allure_list = '--allure_features=Home,Personal' args = ['-s', '-q', '--alluredir', xml_report_path, allure_list] log.info('Execution case set is: %s' % allure_list) self_args = sys.argv[1:] pytest.main(args) cmd = 'allure generate %s -o %s' % (xml_report_path, html_report_path) try: shell.invoke(cmd) except: log.error('Execution of the test case failed, please check the environment configuration') raise try: mail = Email.SendMail() mail.sendMail() except: log.error('Failed to send email, please check email configuration') raise
5. err.log example
[ERROR 2018-08-24 09:55:37]Response body != expected_msg, expected_msg is {"error":"Please register or log in before continuing."}, body is {"error":" Please register or log in before continuing."} [ERROR 2018-08-24 10:00:11]Response time > expected_time, expected_time is 400, time is 482.745 [ERROR 2018-08-25 21:49:41]statusCode error, expected_code is 208, statusCode is 200
6. Assert part of the code
def assert_body(self, body, body_msg, expected_msg): """ Verify the value of any attribute in the response body :param body: :param body_msg: :param expected_msg: :return: """ try: msg = body[body_msg] assert msg == expected_msg return True except: self.log.error("Response body msg != expected_msg, expected_msg is %s, body_msg is %s" % (expected_msg, body_msg)) Consts.RESULT_LIST.append('fail') raise def assert_in_text(self, body, expected_msg): """ Verify that the response body contains the expected string :param body: :param expected_msg: :return: """ try: text = json.dumps(body, ensure_ascii=False) # print(text) assert expected_msg in text return True except: self.log.error("Response body Does not contain expected_msg, expected_msg is %s" % expected_msg) Consts.RESULT_LIST.append('fail') raise
7. Request part code
def post_request(self, url, data, header): """ Post request :param url: :param data: :param header: :return: """ if not url.startswith('http://'): url = '%s%s' % ('http://', url) print(url) try: if data is None: response = self.get_session.post(url=url, headers=header) else: response = self.get_session.post(url=url, params=data, headers=header) except requests.RequestException as e: print('%s%s' % ('RequestException url: ', url)) print(e) return() except Exception as e: print('%s%s' % ('Exception url: ', url)) print(e) return() # time_consuming is the response time in milliseconds time_consuming = response.elapsed.microseconds/1000 # time_total is the response time in seconds time_total = response.elapsed.total_seconds() Common.Consts.STRESS_LIST.append(time_consuming) response_dicts = dict() response_dicts['code'] = response.status_code try: response_dicts['body'] = response.json() except Exception as e: print(e) response_dicts['body'] = '' response_dicts['text'] = response.text response_dicts['time_consuming'] = time_consuming response_dicts['time_total'] = time_total return response_dicts
4. Allure report and email
1. Overview of Allure report, see the picture below:
2. Email is shown below:
5. Subsequent optimization
1. Integrate Jenkins and use the Jenkins plug-in to generate Allure reports
2. Multi-threaded concurrent interface automated testing
3. Interface encryption and parameter encryption
Finally, I would like to thank everyone who read my article carefully. Reciprocity is always necessary. Although it is not a very valuable thing, if you can use it, you can take it directly:
This information should be the most comprehensive and complete preparation warehouse for [software testing] friends. This warehouse has also accompanied tens of thousands of test engineers through the most difficult journey. I hope it can also help you!
The knowledge points of the article match the official knowledge archives, and you can further learn relevant knowledge. Cloud native entry-level skills treeInfrastructure automatic orchestration (Terraform)Introduction to Terraform 16876 people are learning the system