Python测试的一些知识

几个使用UnitTest创建自动化测试框架的小想法

2017-07-28  本文已影响108人  slords

在使用当使用Unittest进行自动化测试框架构建时,会根据测试的种类和需要对测试用的class进行封装。所以,如何进行封转更为用户友好很重要,下面以url接口测试为需求,提出一些想法。

import unittest
import requests
from types import MethodType 

class TestFactroy():

    def run_all_cases(self):
        unittest.main()

    def url_test(self, url, method='get', status_code=200):
        def do_set_up():
            def setUp(self):
                pass
            return setUp

        def extra_test(self, resp, status_code):
            self.assertEqual(resp.status_code, status_code, 'url test status_code fail')
            return

        def do_test_case(url, method, status_code):
            def test_case(self):
                resp = requests.request(url=url,method=method)
                self.extra_test(resp, status_code)
            return test_case

        def add_url_case(cls, url, method='get', status_code=200):
            def one_test_case(self):
                resp = requests.request(url=url,method=method)
                self.assertEqual(resp.status_code, status_code, 'url test status_code fail')
            setattr(cls, "test_case_%s" % cls.case_num, one_test_case)
            cls.case_num += 1
            return

        class TestUrlCase(unittest.TestCase):
            pass
        TestUrlCase.setUp = do_set_up()
        TestUrlCase.test_case = do_test_case(url, method, status_code)
        TestUrlCase.case_num = 1
        TestUrlCase.extra_test= extra_test
        TestUrlCase.add_url_case = MethodType(add_url_case, TestUrlCase)
        return TestUrlCase


if __name__ == "__main__":
    test_factory = TestFactroy()
    test_case_1 = test_factory.url_test("http://www.acfun.cn")
    test_case_2 = test_factory.url_test("http://www.bilibili.com")
    test_case_1.add_url_case("http://www.tucao.tv")
    test_factory.run_all_cases()
import unittest
import requests
from enum import Enum


class UA(Enum):
    Opera = "User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36 OPR/46.0.2597.39"
    Firefox = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"
    chrome = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"


def url_required(func):
    def _url_required(self, *args, **kwargs):
        if self.url is None:
            raise(UrlRequiredException())
        else:
            return func(self, *args, **kwargs)
    return _url_required


class UrlRequiredException(Exception):
    def __init__(self):
        Exception.__init__(self, 'url cannot be None')


class RequestException(Exception):
    def __init__(self, e, http_options):
        msg = "http request failed\n%s\n%s" % \
            (('\n').join([(': ').join(item) for item in http_options.items()]), \
             e.message)
        Exception.__init__(self, msg)

class UrlTestModule(object):

    method = "get"
    url = None
    authentication = False
    encode =False
    user_agent = None
    headers = {}
    params = {}
    data = ""
    ua = None
    response = None
    
    clear_response = False
    
    assert_status_code = 200
    
    exception_list = []
    
    @staticmethod
    def run_test_case():
        unittest.main()
    
    @classmethod
    def set_response(cls, response):
        cls.response = response
    
    @classmethod
    def remove_response(cls):
        cls.response = None
    
    @classmethod
    def get_response(cls):
        return cls.response

    def setUp(self):
        self._initialization()
        self._do_request()
        
    @url_required
    def _do_request(self):
        if self.response is not None:
            return
        http_options = {
            'method': self.method,
            'url': self.url,
            'params': self.params,
            'data': self.data
        }
        headers = {}
        if self.ua:
            headers.update({'User-Agent':self.ua})
        if self.authentication:
            headers.update(self._auth())
        headers.update(self.headers)
        http_options['headers'] = headers
        if self.encode:
            http_options = self._encode(http_options)
        try:
            response = requests.request(**http_options)
            self.set_response(response)
        except Exception as e:
            raise( RequestException(e, http_options))

    @url_required
    def tearDown(self):
        self._finish()
        self._clear_response()
    
    def _initialization(self):
        if hasattr(self,'initialization'):
            m = getattr(self,'initialization')
            if hasattr(m, '__call__'):
                m()
        return
        
    def _finish(self):
        if hasattr(self,'finish'):
            m = getattr(self,'finish')
            if hasattr(m, '__call__'):
                m()
        return
    
    def _clear_response(self):
        if self.assert_status_code:
            self.remove_response()
    
    def _auth(self, *args, **kwargs):
        return {}
        
    def _encode(self, http_options):
        return http_options
    
    def _assert_response_status_code(self):
        if self.assert_status_code:
            if not isinstance(self.assert_status_code, int):
                status_code = 200
            else:
                status_code = self.assert_status_code
            self.assertEqual(self.response.status_code, status_code)

    def _raiseExceptions(self):
        if len(self.exception_list):
            raise(Exception(('\n').join([e.message for e in self.exception_list])))
    
    @url_required   
    def test_script(self):
        self._assert_response_status_code()
        assert_list = [attr for attr in dir(self) \
             if ('check' == attr[:5]) and hasattr(getattr(self, attr),'__call__')]
        assert_list.sort() 
        for m in assert_list:
            try:
                getattr(self, m)()
            except Exception as e:
                self.exception_list.append(e)
        self._raiseExceptions()
                
            
class TestFactory(object):
    @property
    def UrlTest(self):
        class UrlTestClass(UrlTestModule, unittest.TestCase):pass
        return UrlTestClass

    def run_test_case(self):
        unittest.main()
        

test_factory = TestFactory()


if __name__ == "__main__":
    class TestCase(test_factory.UrlTest):

        url= "http://www.bilibili.com"

        def initialization(self):
            print("initialization start")

        def check_if_the_site_is_BiliBili(self):
            print('check if the site is BiliBili start')
            self.assertRegex(self.response.content, "哔哩哔哩".encode('utf-8'))
            
        def check_if_return_html(self):
            print('check if return html start')
            self.assertEqual(self.response.headers.get('Content-Type'), "text/html")

        def finish(self):
            print('finish start')
    
    test_factory.run_test_case()

一些问题

上一篇下一篇

猜你喜欢

热点阅读