preface:
Interface automation refers to the automation at the interface level of analog program. Because the interface is not easy to change and the maintenance cost is less, it is deeply loved by major companies.
Interface automation includes two parts: functional interface automation test and concurrent interface automation test.
This article focuses on the first, functional interface automation framework.
For framework upgrade, please move to: Interface automation framework 2 - upgraded version (Pytest+request+Allure)
1, Brief introduction
Environment: Mac, Python 3, Pytest, Allure, Request
pytest==3.6.0 pytest-allure-adaptor==1.7.10(Discard) pytest-rerunfailures==5.0 configparser==3.5.0 PyYAML==3.12 requests==2.18.4 simplejson==3.16.0 ---------------------------------------- 2020-4-30 to update pytest==5.3.1 allure-pytest==2.8.6 allure-python-commons==2.8.6 ⚠️Note: pytest-allure-adaptor Deprecated, replaced by allure-pytest; install allure-pytest If necessary, the pytest-allure-adaptor uninstall
Process: read Yaml test data - generate test cases - execute test cases - generate Allure Report
Design description of module class:
Request.py encapsulates the request method and supports multi protocol extension (get\post\put)
Config.py reads configuration files, including configurations of different environments and email related configurations
Log.py encapsulates log recording methods, which are divided into debug, info, warning, error and critical
Email.py encapsulates the smtplib method and sends an email notification of the running result
Assert.py encapsulation 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:
Code structure png
2. The framework process is shown in the figure below:
Framework process jpg
3, Detailed functions and instructions
1. Define configuration file config ini
The file distinguishes between the test environment [private_debug] and the formal environment [online_release] and defines relevant configuration items respectively, and the [mail] part is 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=wang@user.com&password=123456 [online_release] # release official service tester = your name environment = release versionCode = v1.0 host = www.jianshu.com loginHost = /Login loginInfo = email=wang@user.com&password=123456 [mail] #Send email message smtpserver = smtp.163.com sender = test1@163.com receiver = wang@user.com username = wang@user.com password = 123456
2. Package after reading yaml test data
See Section 1 for an example of yaml test data. One interface can define multiple case data, get_parameter refers to the encapsulated method of reading yaml data. After cyclic reading, multiple case data are 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: @allure.feature('Home') @allure.severity('blocker') @allure.story('Basic') def test_basic_01(self, action): """ Use case description: viewing 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 whole framework run py
if __name__ == '__main__': # Define test set args = ['-s', '-q', '--alluredir', xml_report_path] 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('Failed to execute the use case. Please check the environment configuration') raise try: mail = Email.SendMail() mail.sendMail() except: log.error('Failed to send mail. Please check the mail configuration') raise
5,err.log instance
[ERROR 2018-08-24 09:55:37]Response body != expected_msg, expected_msg is {"error":"Please register or log in 9 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 code
def assert_body(self, body, body_msg, expected_msg): """ verification response body The value of any attribute in the :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): """ verification response body Does the contain 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. The overview of Allure report is shown in the figure below:
Allure report png
2. See the following figure for Email:
Email.png
5, Subsequent optimization
1. Integrate Jenkins and generate Allure report using Jenkins plug-in
2. Automatic testing of multithreaded concurrent interface
3. Interface encryption
Open source code: https://github.com/wangxiaoxi3/API_Automation
The following is the supporting materials. For friends who do [software testing], it should be the most comprehensive and complete war preparation warehouse. This warehouse has also accompanied me through the most difficult journey. I hope it can also help you!
Finally, it can be in the official account: programmer Hao! Get a 216 page interview document of Software Test Engineer for free. And the corresponding video learning tutorials for free!, It includes basic knowledge, Linux essentials, Shell, Internet program principles, Mysql database, special topics of packet capture tools, interface test tools, test advanced Python programming, Web automation test, APP automation test, interface automation test, advanced continuous integration of test, test architecture, development test framework, performance test, security test, etc.
If my blog is helpful to you and you like my blog content, please click "like", "comment" and "collect" for three times! Friends who like software testing can join our testing technology exchange group: 779450660 (there are various software testing resources and technical discussions)