UI自动化,换种思路,把执行步骤换成动图gif

看了很多UI自动化框架,无论是开源的还是自己造轮子的,都是失败后截最后一张图或几张图。随然没有问题。但我们能不能换种思想。我们能不能把截图全转成gif动图,这样定位问题更直观呢。

来吧。看看怎么实现吧。

先看看楼主的思路吧,如下:

每一个用例中的步骤我们都截图,然后再保存至对应用例的文件夹中,在跑完用例后,将文件夹中的图片转成gif文件,再删除其它静态图片。

思路有了,再看看怎么实现吧。背景是我们用的pytest框架,基于unitest Fixture

一、解析用例名

这步主要是用于获取用例名,用于后面新建对应的用例名文件夹

def get_testname(self):
        full_stack = inspect.stack()
        index = -1
        for stack_frame in full_stack:
            print(stack_frame[1],stack_frame[3])
            if 'test_' in stack_frame[3]:
                index = full_stack.index(stack_frame)
                break
        testname = full_stack[index][3]

        return testname

其中,这里筛选出来的是以含有test_的用例。可根据需要自己修改。

二、截图的保存

 这里的思路就是每一个用例根据用例名创建文件夹,然后再将截图存入

def save_screenshot(self,screenshot_name):
        "Take a screenshot"
        self.screenshots_parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'screenshots'))
        if not os.path.exists(self.screenshots_parent_dir):
            os.makedirs(self.screenshots_parent_dir)
        self.logs_parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'log'))
        if not os.path.exists(self.logs_parent_dir):
            os.makedirs(self.logs_parent_dir)
        self.screenshot_dir = self.screenshots_parent_dir + os.sep + self.gettestname()
        if not os.path.exists(self.screenshot_dir):
            os.makedirs(self.screenshot_dir)
        if os.path.exists(self.screenshot_dir + os.sep + screenshot_name+'.png'):
            for i in range(1,100):
                if os.path.exists(self.screenshot_dir + os.sep +screenshot_name+'_'+str(i)+'.png'):
                    continue
                else:
                    os.rename(self.screenshot_dir + os.sep +screenshot_name+'.png',self.screenshot_dir + os.sep +screenshot_name+'_'+str(i)+'.png')
                    break
        screenshot_name = self.screenshot_dir + os.sep + screenshot_name+'.png'
        self.driver.get_screenshot_as_file(screenshot_name)

三、写装饰器用于步骤的截图

class Wrapit():

    def _screenshot(func):
        def wrapper(self, *args, **kwargs):
            result = func(self, *args, **kwargs)
            screenshot_name = '%003d' % self.screenshot_counter + '_' + func.__name__
            self.screenshot_counter += 1
            self.save_screenshot(screenshot_name)
            return result
        return wrapper

为了防止步骤一样,导致文件名重叠,所以加了一个计数器

 

四、将装饰器用于动作的封装中

@Wrapit._screenshot
def input_name(self, text):
    self.driver.find_element_by_id('kw').send_keys(text)

五、生成gif

这步需要用于Pillow库

def make_gif(self, screenshot_dir_path, name = "test_png",suffix=".gif",duration=500):
        images = []
        from PIL import Image
        filenames = os.listdir(screenshot_dir_path)
        gif_name = os.path.join(screenshot_dir_path, name + suffix)
        for files in sorted(filenames):
            im = Image.open(os.path.join(screenshot_dir_path, files))
            images.append(im)
        images[0].save(gif_name, save_all=True, loop=True, append_images=images[1:], duration=duration)

六、删除其它png文件

def clean_png(self, screenshot_dir_path):
        filenames = os.listdir(screenshot_dir_path)
        fileanames = [name for name in filenames if name.endswith('.png')]
        for files in sorted(fileanames):
            print('remove file %s' % files)
            os.remove(os.path.join(screenshot_dir_path, files))

7、将生成gif和删除png动作放在teardown中

def tearDown(self) -> None:
    self.page.make_gif(self.page.screenshot_dir)
    self.clean_png(self.page.screenshot_dir)

完成后,会生成如果这样的gif

我的用例步骤是:

1.打开百度

2.输入xxxx

3.点击百度一下

4.再点击百度首页

 

 

------可能问题-----

你可能会问到。如果使用的是类继承,导致用例名是一样的,怎么处理?只需要修改获取用例名的函数的方法

未放完整的代码上去。如果有需要的朋友可以直接联系,一起探讨。

还需要优化的地方:

点击某个地方或者找某个元素,需要高亮一下。这样让定位更清晰

 

posted @ 2022-04-11 16:20  Believer007  阅读(233)  评论(1编辑  收藏  举报