The company's internal software using B/s architecture, most of the data are added and deleted, because it is still in the development phase, so the UI interface changes very fast, it is difficult to test the UI for automation, that will consume a lot of effort and time to maintain the automation script. For this case, the interface test is more effective.
Tool selection
There are also many tools for interface testing, such as the soup UI, the robot framework, and even jmeter performance test tools that can be tested for interfaces.
The robot framework testing framework has a number of third-party libraries that can be used with a form-fill approach, which is easier to use, but does not penetrate the underlying understanding of the client-server interaction process. JMeter such a focus on performance testing tools, interface testing, a bit overqualified feeling and unable to generate test reports.
In consideration, decided to develop a simple framework, the advantages are flexible enough, can be changed at any time according to requirements, the background is using Python flask development, the use of Python 2.7.11 framework development, Python development is fast, and easy to use, The rich third-party library, greatly accelerates the development speed and the difficulty.
Frame ideas
Because it is a framework, consider the reusability and maintainability of the framework. The data-driven design method is used to layer the data and split the business logic. This allows testers to focus on writing test cases through data files, without paying attention to coding and improving efficiency. The framework uses basic Excel for data management. Data is obtained by reading to Excel.
The test results are then generated in HTML-formatted test reports sent to the relevant developer.
Introduction to the third party libraries
Requests
Python has many libraries for HTTP, such as its own urllib2, but its own urllib2 is too much effort to write, so it uses the requests library known as "HTTP for humans".
Xlrd
XLRD makes it easy for Python to read and write to Excel files, this time reading the test data in an Excel file by xlrd.
The above third-party libraries can be installed via PIP directly or via PyPI download source package.
Module Introduction
Get_conf: Read the configuration file, get the message sent configuration information, such as SmtpServer, receiver, sender and so on.
Md5encode: Some data are transmitted by MD5 encryption, so the data read from Excel needs to be MD5 encrypted.
SendMail: When the test is complete, the test report is automatically sent to the relevant developer.
Runtest: This section reads the data in Excel, calls the Interfacetest method below, and saves the information returned by the interfacetest.
Interfacetest: The Excel data read by Runtest is used as an entry parameter, the interface test is performed, and the information returned from the background is returned to Runtest.
Excel
I do not know how to upload the picture has failed, the Excel file format will be uploaded later
Code implementation
#通过自带的ConfigParser模块, read the message sent by the configuration file as a dictionary returned import Configparserdef get_conf (): conf_file = Configparser.configparser () conf_file.read (Os.path.join (OS.GETCWD (), ' Conf.ini ') conf = {} conf[' Sender '] = conf_file.get ("email", "sender") conf[' receiver '] = conf_file.get ("email", "receiver") conf[' SmtpServer '] = conf_file.get ("email", "smtpserver") conf[' username '] = conf_file.get ("email", "username") conf[' Password ' = conf_file.get ("email", "password") return conf
#此处使用python自带的logging模块, which is used as a test log to record the information generated by the system in the test. Import logging,oslog_file = Os.path.join (OS.GETCWD (), ' log/sas.log ') log_format = ' [% (asctime) s] [% (levelname) s]% ( Message) s ' Logging.basicconfig (Format=log_format, Filename=log_file, filemode= ' W ', level=logging. DEBUG) Console = logging. Streamhandler () Console.setlevel (logging. DEBUG) formatter = logging. Formatter (Log_format) console.setformatter (Formatter) Logging.getlogger ("). AddHandler (console)
#读取testcase the Excel file, get the test data, call the Interfacetest method, and save the results to the Errorcase list. Import Xlrd,hashlib,jsondef runtest (testcasefile): Testcasefile = Os.path.join (OS.GETCWD (), testcasefile) if not Os.path.exists (Testcasefile): logging.error (' Test case file does not exist! ') sys.exit () TestCase = Xlrd.open_workbook (testcasefile) Table = Testcase.sheet_by_index (0) error case = [] #用于保存接口返回的内容和HTTP状态码 s = None for I in Range (1,table.nrows): If Table.cell (i , 9). Vale.replace (' \ n ', '). Replace (' \ R ', ')! = ' Yes ': Continue num = str (int (Table.cell (i, 0). VA Lue). replace (' \ n ', '). Replace (' \ R ', ') Api_purpose = Table.cell (i, 1). Value.replace (' \ n ', '). Replace (' \ R ', ') Api_host = Table.cell (i, 2). Value.replace (' \ n ', '). Replace (' \ R ', ') Request_method = Table.cell (i, 4 ). Value.replace (' \ n ', '). Replace (' \ R ', ') Request_data_type = Table.cell (i, 5). Value.replace (' \ n ', '). Replace (' \ r ', ') Request_data = Table.cell (i, 6). Value.replace (' \ n ', '). Replace (' \ R ', ') encryption = Table.cell (i, 7). Value.re Place (' \ n ', '). Replace (' \ R ', ') Check_point = Table.cell (i, 8). value if encryption = = ' MD5 ': #如果数据采用md5加密, encrypt the data first request_data = Json.loads (request_data) request_data[' pwd '] = MD5 Encode (request_data[' pwd ') status, resp, s = interfacetest (num, Api_purpose, Api_host, Request_url, Request_da Ta, Check_point, Request_methon, Request_data_type, s) if status! = or Check_point not in RESP: #如果状态码不为200或者返回值中没有检查点的内容, it proves that the interface generates an error and holds the error message. Errorcase.append (num + "+ api_purpose, str (status), '/HTTP//' +api_host+request_url, resp)" Return errorcase
#接受runTest的传参, construct HTTP requests using requests import Requestsdef interfacetest (num, Api_purpose, Api_host, Request_method, Request_data_type, Request_data, Check_point, s=none) headers = {' Content-type ': ' Application/x-www-form-urlencod Ed Charset=utf-8 ', ' x-requested-with ': ' XMLHttpRequest ', ' Connection ': ' Keep-aliv E ', ' Referer ': ' http//' + api_host, ' user-agent ': ' mozilla/5.0 (Windows NT 6. 1; WOW64) applewebkit/537.36 (khtml, like Gecko) chrome/49.0.2623.110 safari/537.36 '} if s = = None: s = requests.session () if Request_method = = ' POST ': if request_url! = '/login ': r = S.post ( Url= '/http ' +api_host+request_url, data = Json.loads (request_data), headers = headers) #由于此处数据没有经过加密, so the JSON format word needs to be String decoding converted to **python object * * elif Request_url = = '/login ': s = requests.session () r = s.post (Ur L= ' http//' +api_hOst+request_url, data = request_data, headers = headers) #由于登录密码不能明文传输, with MD5 encryption, has been json.loads () converted in the previous code, so there is no need to Decoding else:logging.error (num + ' + api_purpose + ' HTTP request method error, please confirm the [Request Method] field is correct!!! ') s = None return, resp, s status = R.status_code resp = r.text Print resp if statu s = = 200:if Re.search (check_point, str (r.text)): logging.info (num + ' + api_purpose + ' success, ' + STR (s) tatus) + ', ' + str (r.text)) return status, RESP, s else:logging.error (num + "+ Api_purpo SE + ' Failure!!! , [' + str (status) + '], ' + str ' (R.text)) return, RESP, None else:logging.error (num + ') ' + Api_purpose + ' Failure!!! , [' + str (status) + '], ' + str ' (R.text)) return status, Resp.decode (' Utf-8 '), None
Import hashlibdef Md5encode (data): Hashobj = Hashlib.md5 () hashobj.update (Data.encode (' Utf-8 ')) return hash Obj.hexdigest () def sendMail (text): Mail_info = get_conf () sender = mail_info[' sender '] receiver = Mail_info [' receiver '] subject = ' [AutomationTest] interface Automated test report notification ' SmtpServer = mail_info[' smtpserver '] username = mail_i nfo[' username ' password = mail_info[' password '] msg = mimetext (text, ' HTML ', ' Utf-8 ') msg[' Subject '] = Subje CT msg[' from ' = Sender msg[' to '] = '. Join (receiver) SMTP = Smtplib. SMTP () smtp.connect (smtpserver) smtp.login (username, password) smtp.sendmail (sender, receiver, Msg.as_strin g ()) Smtp.quit () def main (): Errortest = runtest (' testcase/testcase.xlsx ') If Len (errortest) > 0: html = ' Since all the operations must be done after the system has logged in, the cookie is not noticed at first, and each time a test case is read, a new session is created, resulting in the inability to maintain the cookie for the last request. The cookie is then added to the request header, but the second use case still fails to execute successfully. Later with fiddler grab Packet Analysis, found that the value of the cookie is every operation will change!!!
Therefore, cookies can only be maintained automatically through the session. In the Interfacetest function, three values are returned, namely the HTTP Code,http return value and the session. Then the last request session as input into the Interfacetest function, inside the function to determine whether the session exists, if not none, then directly using the incoming session to execute the next use case, if none, Then create a new session.
The shortcomings
- The framework is very primitive, just the implementation of simple ideas, the details of the coding is not perfect.
- HTML test reports are difficult to write, consider introducing a third-party library to write HTML test reports, and send the resulting HTML file as an attachment.
- Only for the company's internal software, exchange for other platforms is not applicable, need to modify the source code.
- Reprint: Reprint: http://www.zuimoban.com/jiaocheng/python/7375.html
Python-based Interface Automation testing framework