解决截图乱码问题

/usr/local/selenium_grid/fonts
[root@VM-24-13-centos fonts]# ll
总用量 65268
-rw-r--r-- 1 root root 16829116 3月  24 18:15 msyhbd.ttc
-rw-r--r-- 1 root root 12139380 3月  24 18:15 msyhl.ttc
-rw-r--r-- 1 root root 19647736 3月  24 18:14 msyh.ttc
-rw-r--r-- 1 root root 18214472 3月  24 18:15 simsun.ttc

docker-compose

pip3 install docker-compose
chrome: 
  image: selenium/node-chrome:3.8.1
  links:
    - hub:hub # 这里是把挂载到hub下面的意思
  ports: 
    - "5902:5900" # 给vnc调试用
  environment: 
    - NODE_MAX_INSTANCES=5 # 实例化和下面参数一般保持一致,可以多机并行
    - NODE_MAX_SESSION=5
    - SCREEN_WIDTH=1920 
    - SCREEN_HEIGHT=1080 
  volumes:
    - /dev/shm:/dev/shm # 挂载这个持久化数据,据说是为了防止不同的闪退
    - ./fonts:/usr/share/fonts # 把中文字体挂载进来,解决截图乱码问题

hub: 
  image: selenium/hub:3.8.1
  ports: 
    - "7777:4444" # 7777为外部web访问端口
docker-compose up -d

 pip3 install selenium

import time

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from multiprocessing import Process

print(11111)
# ip = "远程ip"
ip = "localhost"
driver = webdriver.Remote(
    command_executor="http://%s:7777/wd/hub" %ip,
    desired_capabilities=DesiredCapabilities.CHROME
)
print(22222)

def test(i):
    time.sleep(3)
    driver.get("https://www.baidu.com")
    print(driver.title, i)


if __name__ == '__main__':
    test(1)
    driver.close()
    driver.quit()

pytest 分布式执行

环境搭建

pip install pytest
pip install pytest-xdist
pip install pytest-html
D:\app\Python37\Lib\site-packages\pytest_html\plugin.py

   class TestResult:
        def __init__(self, outcome, report, logfile, config):
            #self.test_id = report.nodeid.encode("utf-8").decode("unicode_escape")
            self.test_id = re.sub(r'(\\u[a-zA-Z0-9]{4})',lambda x:x.group(1).encode("utf-8").decode("unicode-escape"),report.nodeid)

# conftest.py
import pytest
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from py._xmlgen import html

_driver = None


# @pytest.fixture()
@pytest.fixture(scope='session', autouse=True)
def driver():
    global _driver
    print(11111)
    ip = "远程ip"
    server = "http://%s:7777/wd/hub" % ip
    # ip = "localhost"
    _driver = webdriver.Remote(
        command_executor="http://%s:7777/wd/hub" % ip,
        desired_capabilities=DesiredCapabilities.CHROME
    )
    # 返回数据
    yield _driver
    # 实现用例后置
    _driver.close()
    _driver.quit()


@user3per
def pytest_runtest_makereport(item):
    """
    当测试失败的时候,自动截图,展示到html报告中
    :param item:
    """
    if not _driver:
        return
    pytest_html = item.config.pluginmanager.getplugin('html')
    outcome = yield
    report = outcome.get_result()
    report.description = str(item.function.__doc__)
    extra = getattr(report, 'extra', [])

    if report.when == 'call' or report.when == "setup":
        xfail = hasattr(report, 'wasxfail')
        if (report.skipped and xfail) or (report.failed and not xfail):
            screen_img = _capture_screenshot()
            if screen_img:
                html = '<div><img src="data:image/png;base64,%s" alt="screenshot" style="width:1024px;height:768px;" ' \
                       'onclick="window.open(this.src)" align="right"/></div>' % screen_img
                extra.append(pytest_html.extras.html(html))
        report.extra = extra


def pytest_html_results_table_header(cells):
    cells.insert(1, html.th('用例名称'))
    cells.insert(2, html.th('Test_nodeid'))
    cells.pop(2)


def pytest_html_results_table_row(report, cells):
    cells.insert(1, html.td(report.description))
    cells.insert(2, html.td(report.nodeid))
    cells.pop(2)


def pytest_html_results_table_html(report, data):
    if report.passed:
        del data[:]
        data.append(html.div('通过的用例未捕获日志输出.', class_='empty log'))


def pytest_html_report_title(report):
    report.title = "pytest示例项目测试报告"

def _capture_screenshot():
    """
    截图保存为base64
    :return:
    """
    return _driver.get_screenshot_as_base64()
# test_selenium.py

mport os
import time
import pytest

class TestCase(object):
    @pytest.mark.finished
    def test_001(self, driver):
        time.sleep(3)
        driver.get("https://www.baidu.com")
        print(driver.title)
        driver.find_element_by_id("kw").click()
        driver.find_element_by_id("kw").send_keys("你好")
    def test1_001(self, driver):
        time.sleep(3)
        driver.get("https://www.baidu.com")
        print(driver.title)
        driver.find_element_by_id("kw").click()
        driver.find_element_by_id("kw").send_keys("你好")
# runner.py

import os
from multiprocessing import Process

import pytest


def main(path):
    # 这里的-n 3 意思就是同时并发3个用例执行
    pytest.main(['%s' %path,'-n 3', '--html=report.html','--self-contained-html', '--capture=sys'])


if __name__ == '__main__':

    test_case = Process(target=main, args=("d:\\project\\py_selenium_grid\\testcase\\大回归\\",))
    test_case.start()
    test_case.join()
    ...
    直接用pytest 命令执行
    ...

总结

我在【TesterHome 系列征文活动 | 自动化测试实践】等你,一起 day day up!


↙↙↙阅读原文可查看相关链接,并与作者交流