将Capybara的screenshot上传至阿里云的OSS

写在前面

网页测试中,有一个很棒的gem叫capybara-screenshot ,当你的scenario失败时,会自动将网页进行截图。

当然,你也可以手动截图。比如我想看看在step A中,我停留的网页长什么样子,直接用Capybara::Screenshot.screenshot_and_open_image, 终端运行cucumber或者rspec时,就可以看到网页的模样。

截图下来的图片,如果保存在本地,随着scenario的增多,自然会吃不消的,使用云存储是个好选择,比如放在阿里云上,还能通过生成的URL来将截图呈现在网页上,非常棒。

【当然你也可以在capybara中设置Capybara::Screenshot.prune_strategy的值,只保存最后的XX个或者最后一次运行的截图,这样截图就不会很多,但这里不讨论这种情况】

下面,简单来走一走如何将截图上传至阿里云的OSS。

正文

以howitzer_cucumber的一个登陆测试为例,来看看如何将截图传至阿里云。

  • 开通阿里云的OSS服务【点击,按照指示下单购买即可】

  • 新建存储空间bucket,获取你的aliyun_access_key, aliyun_secret_key,host【存储空间概览下面的endpoint】

  • 在gemfile中添加gem 'aliyun-oss-sdk', 终端运行bundle install

  • features/support中新建文件aliyun.rb,试试上传一张图片:

    require 'aliyun/oss'
    aliyun_access_key = "你的access_key"
    aliyun_secret_key = "你的secret_key"
    host = '你的host'
    bucket = '你的bucket'
    client = Aliyun::Oss::Client.new(aliyun_access_key, aliyun_secret_key, host: host, bucket: bucket)
    client.bucket_create_object('images/image.png', File.new(/Users/xxx/xxx/image.png), {'Content-Type' => 'image/png' })
    

    这里File.new中的参数,是你想要上传的本地图片的文件路径。

    终端运行该脚本,在你刚刚新建的bucket中,查看“文件管理”,你会发现已经上传成功,很赞有没有?

  • 接着我们上传截图,比如登陆测试的scenario长这样:

      Scenario: 用户输入正确的邮箱和密码完成登录
        Given 我是已经注册的用户"管理员张三"
        And  我在登录页面
        When 我在登录页面的表格中输入邮箱:"[email protected]"和密码:"Password123456"
        And 我点击登录按钮,提交表单
        Then 我可以看到我已经进入了个人的主页
    

    现在我要截图一下登陆页面,可以这么来, 在对应的step的定义中,添加代码:

    And(/^我在登录页面$/) do
      LoginPage.open
     + LoginPage.on do
     +   file = Capybara::Screenshot.screen_shot_and_save_page
     + end
    end
    

    到这里你自然会想到,需要将上传这一步进行封装调用,我们先封装一下图片上传。

    考虑到Capybara::Screenshot.screen_shot_and_save_page得到的是一个hash,而我们想要的其实是截图的文件路径,所以用Dir.pwd + file[:image].sub('.','') 来获取截图路径。

    修改aliyun.rb文件:

    require 'aliyun/oss'
    
    aliyun_access_key = "你的access_key"
    aliyun_secret_key = "你的secret_key"
    host = '你的host'
    bucket = '你的bucket'
    $client = Aliyun::Oss::Client.new(aliyun_access_key, aliyun_secret_key, host: host, bucket: bucket)
    
    module AliyunClient
      module Client
        def upload_image(filename, file)
          image_file = Dir.pwd + file[:image].sub('.','')
          $client.bucket_create_object(filename, File.new(image_file), {'Content-Type' => 'image/png' })
        end
      end
    end
    
    class Object
      include AliyunClient::Client
    end
    

    封装好了,直接调用我们的upload_image吧!

    在刚刚的step的定义中,添加代码:

    And(/^我在登录页面$/) do
      LoginPage.open
      LoginPage.on do
        file = Capybara::Screenshot.screen_shot_and_save_page
     +   upload('images/image.png', file)
      end
    end
    

    OK!!

    这里,我是上传到images文件夹下,文件名为image.png 。当然具体上传的目标文件及文件夹都是可以自定义的,也是需要自定义的,特别是多次上传,你肯定不希望图片都被覆盖掉了,具体可以查看aliyun-oss-ruby-sdk

参考

aliyun-oss-ruby-sdk

capybara-screenshot