Python 40行代码实现HttpRunner(动态创建类,动态添加方法,模板解析)

最近偶然看到了一些关于HttpRunner的一些推送(可能是我平时太爱学习了哈哈哈),出于好奇就看了一下HttpRunner的源码哈哈,最后发现实现逻辑是使用元类动态创建测试类,用读取testcase,并用setattr将测试方法添加至测试类~学习过程如下~

  • 第一步pip httprunner,安装成功后进入包下api.py文件看到如下代码,TestSequense = type(‘TestSequense’, (unittest.TestCase,), {})  此处用元类type动态创建了继承unittest的测试类,setattr(TestSequense, test_method_name, test_method) 随后用setattr动态添加了对应测试类的测试方法~嘻嘻搞清楚这个逻辑,那我们就模仿写一个吧~
    for testcase in testcases:
       config = testcase.get("config", {})
       test_runner = runner.Runner(config)
       TestSequense = type('TestSequense', (unittest.TestCase,), {})
       tests = testcase.get("teststeps", [])
    
       for index, test_dict in enumerate(tests):
           times = test_dict.get("times", 1)
           try:
             times = int(times)
           except ValueError:
              raise exceptions.ParamsError( "times should be digit, given: {}".format(times))
           
           for times_index in range(times):
           # suppose one testcase should not have more than 9999 steps,
           # and one step should not run more than 999 times.
           test_method_name = 'test_{:04}_{:03}'.format(index, times_index)
           test_method = _add_test(test_runner, test_dict)
           setattr(TestSequense, test_method_name, test_method)

     

  •  脚本逻辑设计图如下,先将一个个yaml文件动态创建为一个个的测试类,模板解析yaml文件提取testcase,将其转变成测试方法,并动态添加至对应的测试类。
  • yamlcase 提取方法,入参为yamlfile所在的路径,会提取该路径下所有yaml文件,并返回一个字典,键值对为 yamlfilename:yamldata 。(用typing注解)
    def load_yaml_case(file:str = yamlfile )->dict:
        dict_yaml_data ={}
        yaml_file_list = [yaml_file for yaml_file in os.listdir(file) if yaml_file[-4:]=='yaml']  # 输出所有yamlfile路径下的的yaml文件
        for yaml_data in yaml_file_list :
            with open(yamlfile+r'\\'+yaml_data, encoding='utf-8') as f:
                dict_yaml_data[yaml_data] = str(yaml.safe_load(f))  # 依次加载
        return dict_yaml_data
  • 这次测试接口依然采用unittest批量组织依赖用例(组织依赖用例,结果前端展示,测试报告发送 )  这篇文章中的测试接口~
依赖接口

 

  • 并编写如下yaml文件,TestLogic_XX1.yamlTestLogic_XX2.yamlTestLogic_XX3.yaml 内容如下(简单依赖):
    - name: 测试接口一
      request:
        url: http://192.168.11.9:9999/DepenceOne
        data:
        method: get
        save: One
        depence:
    
    - name: 测试接口二
      request:
        url: http://192.168.11.9:9999/DepenceTwo
        data:
          One: $s
        method: post
        save: Two
        depence:
          - One
    
    - name: 测试接口三
      request:
        url: http://192.168.11.9:9999/DepenceThr
        data:
        method: get
        save: Thr
        depence:
    
    
    - name: 测试接口四
      request:
        url: http://192.168.11.9:9999/DepenceFou
        data:
          Thr: $s
        method: post
        save: Fou
        depence:
          - Thr
    
    
    - name: 测试接口五
      request:
        url: http://192.168.11.9:9999/DepenceFive
        data:
          Two: $s
          Fou: $s
        method: post
        save:
        depence:
          - Two
          - Fou
  • 老样子写个装饰器返回request方法(不懂得可以参考之前的文章unittest批量组织依赖用例(生成测试方法))
    def getTestFunc(url,data, method, save, depence):
        def requestRun(self):
            nonlocal data
            if depence:
                data = json.dumps(str(data).replace('$','%') % tuple(getattr(Depence, str(i)) for i in depence))
            if method == 'post':
                req = requests.post(url=url, data=data)
            else:
                req = requests.get(url=url, data=data)
            if save:
                setattr(Depence, save, eval(req.text)[save])
        return requestRun

     

  • 接着创建依赖类(详细参考之前的文章接口自动化中依赖数据的存储方式(列举2种)),这次用type创建(万物皆对象),
    Depence = type('Depence', (), dict())

>>>type(int)
<class ‘type’>
>>>type(str)
<class ‘type’>
>>>type(type)
<class ‘type’>

“元类就是深度的魔法,99%的用户应该根本不必为此操心。如果你想搞清楚究竟是否需要用到元类,那么你就不需要它。那些实际用到元类的人都非常清楚地知道他们需要做什么,而且根本不需要解释为什么要用元类。” —— Python界的领袖 Tim Peters

  • 接着使用之前定义的load_yaml_case方法,根据yaml文件生成对应继承unittest的测试类
    for classname,testcase in load_yaml_case().items():
        globals()[classname[:-5:]] = type(classname[:-5:],(unittest.TestCase,),dict())
  • 紧接着找出该py文件内所有生成的测试类,第一步找出该py下所有类:
    {key: var for key, var in locals().items() if isinstance(var, type)}
  • 第二步剔除非测试类(也就是引入类):
    [str(i) for i  in class_dict.keys() if i not in('Log','Depence','load_yaml_case')]
  • 第三步,取出对应类yaml内的testcase,并分别生成测试方法添加至测试类中:
    for def_data in eval(load_yaml_case()[f'{class_name}.yaml']): #取出当前继承unittest的class的testcase data
         setattr(eval(class_name), 'test_func_%s' % (def_data['name']), getTestFunc(**def_data['request'])) #将testcase data转成def
  • 到此为止该py下全部代码为(20行左右,文件名为:testClass.py):
    def getTestFunc(url,data, method, save, depence):
        def requestRun(self):
            nonlocal data
            if depence:
                data = json.dumps(str(data).replace('$','%') % tuple(getattr(Depence, str(i)) for i in depence))
            if method == 'post':
                req = requests.post(url=url, data=data)
            else:
                req = requests.get(url=url, data=data)
            if save:
                setattr(Depence, save, eval(req.text)[save])
        return requestRun
    
    Depence = type('Depence', (), dict()) #创建依赖类
    for classname,testcase in load_yaml_case().items():
        globals()[classname[:-5:]] = type(classname[:-5:],(unittest.TestCase,),dict())
    class_dict = {key: var for key, var in locals().items() if isinstance(var, type)}
    for class_name in [str(i) for i  in class_dict.keys() if i not in('Log','Depence','load_yaml_case')]: #取出当前继承unittest的class
        for def_data in eval(load_yaml_case()[f'{class_name}.yaml']): #取出当前继承unittest的class的testcase data
            setattr(eval(class_name), 'test_func_%s' % (def_data['name']), getTestFunc(**def_data['request'])) #将testcase data转成def
    
    

     

  • 另起一个testRun.py,导入之前的测试类,利用loadTestsFromModule,导入所有继承unittest的测试类(testClass为测试类所在py的文件名),并引入测试报告:
    suit=unittest.TestLoader().loadTestsFromModule(testClass)
    with open(report_file + r'\TestReport.html', 'wb') as f:  # 从配置文件中读取
       HTMLTestRunner(stream=f, title='Api Test', description='动态类demo', tester='ayo').run(suit)
  • 最后执行testRun.py,哈哈哈成功啦~根据yaml生成了测试类,并根据yaml内容生成了测试方法~:

    report

 

18,020 次浏览

“Python 40行代码实现HttpRunner(动态创建类,动态添加方法,模板解析)”的2,120个回复

  1. obviously like your web site but you have to take a look at the spelling on quite a few of your posts. A number of them are rife with spelling issues and I in finding it very bothersome to tell the reality nevertheless I’ll certainly come back again.|

  2. Incredible update of captchas solving software “XRumer 19.0 + XEvil”:
    captcha solving of Google (ReCaptcha-2 and ReCaptcha-3), Facebook, BitFinex, Bing, Hotmail, SolveMedia, Yandex,
    and more than 12000 another subtypes of captchas,
    with highest precision (80..100%) and highest speed (100 img per second).
    You can use XEvil 4.0 with any most popular SEO/SMM software: iMacros, XRumer, GSA SER, ZennoPoster, Srapebox, Senuke, and more than 100 of other software.

    Interested? There are a lot of introducing videos about XEvil in YouTube.

    Free XEvil Demo available.

    See you later!

    http://XEvil.net

  3. I am glad for commenting to let you understand what a brilliant encounter our princess encountered using your blog. She picked up too many issues, which include how it is like to possess a very effective teaching style to make many more without hassle gain knowledge of chosen very confusing topics. You actually exceeded our own expected results. I appreciate you for presenting such warm and friendly, trusted, explanatory not to mention fun tips about that topic to Janet.

  4. I intended to create you this very little remark to help say thanks as before for these great tips you’ve documented on this page. This has been really surprisingly open-handed of you to deliver freely all many people would’ve distributed as an electronic book to end up making some cash for their own end, most importantly given that you could have done it if you ever considered necessary. Those thoughts in addition acted like the fantastic way to fully grasp other people online have the identical keenness really like mine to know a lot more in respect of this problem. I’m certain there are a lot more pleasurable opportunities in the future for folks who looked over your website.

  5. I wish to get across my admiration for your generosity in support of all those that actually need guidance on the topic. Your personal dedication to getting the message throughout ended up being really informative and has continuously allowed women like me to attain their aims. Your insightful tutorial implies so much a person like me and substantially more to my peers. Many thanks; from each one of us.

  6. Howdy just wanted to give you a quick heads up. The text in your article seem to be running off the
    screen in Firefox. I’m not sure if this is a format issue or something to do with web
    browser compatibility but I thought I’d post to let you know.
    The design and style look great though! Hope you get the issue resolved soon. Kudos

  7. Wow, superb blog format! How long have you ever been blogging for?
    you make blogging glance easy. The entire glance of your
    website is great, as well as the content!

  8. Hiya very cool web site!! Guy .. Excellent ..
    Superb .. I’ll bookmark your site and take the feeds also?
    I am satisfied to find a lot of helpful information right here in the publish, we’d
    like develop more techniques in this regard, thanks for sharing.

    . . . . .

  9. Thank you for all of the hard work on this website. My mum enjoys engaging in investigation and it’s obvious why. Many of us know all about the compelling medium you render efficient ideas through your blog and as well as invigorate response from some other people on the point then our own princess is certainly being taught a great deal. Enjoy the rest of the year. Your carrying out a great job.

  10. Hello very nice site!! Man .. Excellent .. Wonderful ..
    I’ll bookmark your website and take the feeds also? I’m satisfied to
    search out a lot of helpful information here within the post, we’d like develop more techniques in this
    regard, thank you for sharing. . . . . .

  11. I apologize for off-topic, I am thinking about creating an interesting web-site for college students. Will possibly begin with submitting interesting information such as”Negative emotions such as anxiety and depression can weaken your immune system.”Please let me know if you know where I can find some related facts such as here

    Bahsegel

  12. I’m the manager of JustCBD Store company (justcbdstore.com) and I am currently planning to broaden my wholesale side of business. It would be great if someone at targetdomain can help me ! I considered that the most ideal way to accomplish this would be to reach out to vape stores and cbd retailers. I was hoping if someone could suggest a trusted web site where I can purchase CBD Shops B2B Marketing List I am already checking out creativebeartech.com, theeliquidboutique.co.uk and wowitloveithaveit.com. On the fence which one would be the most suitable choice and would appreciate any assistance on this. Or would it be easier for me to scrape my own leads? Suggestions?

  13. Hi, i read your blog from time to time and i own a
    similar one and i was just wondering if you get a lot of spam responses?
    If so how do you reduce it, any plugin or anything you can recommend?
    I get so much lately it’s driving me mad so any help is very much appreciated.

  14. Having read this I thought it was extremely enlightening. I appreciate you taking the time and effort to put this information together. I once again find myself spending a lot of time both reading and leaving comments. But so what, it was still worth it!

  15. hello!,I love your writing so a lot! proportion we keep up a correspondence extra about your article
    on AOL? I require a specialist in this area to unravel my
    problem. Maybe that’s you! Taking a look ahead to look you.

  16. Hi there are using WordPress for your site platform?

    I’m new to the blog world but I’m trying to get started and set up my own. Do you need any coding expertise to make your own blog?
    Any help would be greatly appreciated!

  17. Howdy! This article couldn’t be written much better! Reading through this article reminds me of my previous roommate! He always kept talking about this. I’ll forward this information to him. Pretty sure he’ll have a great read. I appreciate you for sharing!

  18. Whats up this is kind of of off topic but I was
    wanting to know if blogs use WYSIWYG editors or if you have to manually code with HTML.
    I’m starting a blog soon but have no coding experience so I
    wanted to get guidance from someone with experience.
    Any help would be enormously appreciated!

  19. May I simply say what a comfort to uncover an individual who genuinely understands what they’re talking about on the internet. You actually know how to bring a problem to light and make it important. More and more people ought to read this and understand this side of the story. I can’t believe you are not more popular given that you most certainly have the gift.

  20. [url=https://phenergan125.com/]phenergan over the counter in canada[/url] [url=https://arimidex365.com/]cost of arimidex in australia[/url] [url=https://sumycin365.com/]buy sumycin online[/url]

  21. Howdy! I could have sworn I’ve been to this website before but after looking at many of the articles I realized it’s new to me. Anyways, I’m certainly delighted I found it and I’ll be book-marking it and checking back regularly!

  22. [url=https://plavix.us.com/]plavix 75 price in india[/url] [url=https://trazodone911.com/]trazodone order[/url] [url=https://inderal.us.com/]medicine inderal 40[/url]

  23. An interesting discussion is definitely worth comment. There’s no doubt that that you ought to publish more on this subject, it may not be a taboo matter but usually people don’t discuss these issues. To the next! Cheers!!

  24. Oh my goodness! Awesome article dude! Many thanks, However I am going through difficulties with your RSS. I don’t know the reason why I cannot join it. Is there anyone else having identical RSS issues? Anyone that knows the solution will you kindly respond? Thanx!!

  25. A motivating discussion is worth comment. I do think that you ought to publish more about this topic, it might not be a taboo matter but generally folks don’t discuss such subjects. To the next! Best wishes!!

  26. I like to get my inspiration from really meaningful phrases said by truly great people like “Philosophy is a battle against the bewitchment of our intelligence by means of language”, do you know where I can find thematic compiltaions of those?

    [url]http://shinuy.wee.co.il/2020/08/04/bahsegel-giris-sitesi/[/url]

  27. I like to get my inspiration from really meaningful phrases said by truly great people like “I would never die for my beliefs because I might be wrong”, do you know where I can find thematic compiltaions of those?

    [url]http://www.tempnet.reneltbelicdesign.com.au/303-melhores-ideias-de-apostas-esportivas-em-2020/[/url]

  28. Its like you learn my thoughts! You appear to know a lot approximately
    this, such as you wrote the guide in it or
    something. I believe that you can do with a few percent to force the message house a bit, but instead of that, that
    is wonderful blog. A great read. I will definitely be
    back.

  29. I really like your blog.. very nice colors & theme. Did you
    create this website yourself or did you hire someone to do it for you?

    Plz respond as I’m looking to design my own blog and would like to find out where u got
    this from. cheers

  30. [url=https://chydroxychloroquine.com/]plaquenil 400 mg[/url] [url=https://robaxin24.com/]where to buy robaxin 750[/url] [url=https://avanafill.com/]avana 77573[/url] [url=https://furosemide1.com/]can you buy furosemide over the counter in uk[/url] [url=https://estrace2.com/]estrace for sale[/url] [url=https://ciproflxn.com/]cipro over the counter drug[/url] [url=https://acyclovirzov.com/]purchase acyclovir cream[/url] [url=https://vardenafilxr.com/]vardenafil 10mg[/url] [url=https://toradoliv.com/]toradol best price[/url] [url=https://priligydapoxetin.com/]priligy price canada[/url]

  31. Aw, this was an extremely good post. Spending some time and actual effort to make a great article… but what can I say… I put things off a whole lot and don’t manage to get anything done.

  32. Having read this I believed it was extremely informative. I appreciate you spending some time and energy to put this article together. I once again find myself personally spending way too much time both reading and commenting. But so what, it was still worthwhile!

  33. You are so awesome! I do not believe I’ve truly read through something like this before. So good to discover someone with unique thoughts on this topic. Seriously.. many thanks for starting this up. This website is one thing that’s needed on the web, someone with some originality!

  34. I’m impressed, I must say. Seldom do I encounter a blog that’s both equally educative and entertaining, and let me tell you, you have hit the nail on the head. The problem is something that too few people are speaking intelligently about. Now i’m very happy I found this during my search for something relating to this.

  35. Right here is the perfect site for anybody who hopes to understand this topic. You realize a whole lot its almost hard to argue with you (not that I personally would want to…HaHa). You definitely put a new spin on a subject that has been written about for a long time. Wonderful stuff, just excellent!