python库(2)

pybind11

pybind11支持 python和c++相互调用。

安装

conda install pybind11
python -m pybind11 --includes

-IC:\Miniconda3\Include -IC:\Miniconda3\lib\site-packages\pybind11\include

visual studio 2019 中新建空白项目 ProjectCPP。

include python和pybind11的头文件

  • debug 选 x64
  • 项目右键,配置,平台选 x64
  • 项目右键,属性,“VC++目录” > “常规” > “包含目录”属性中,添加路径列表 ,确保删除 -I 前缀(若有)
C:\Miniconda3\Include 
C:\Miniconda3\lib\site-packages\pybind11\include

调整输出类型为dll, 调整输出文件名为pyd

项目右键,属性,常规,配置类型由 exe 修改为 dll。

项目右键,属性,高级,高级属性,扩展名由 .exe 修改为.pyd

链接 python的lib

项目右键,属性,“VC++目录” > “常规” > “库目录”, 添加:

C:\Miniconda3\libs

linker里添加python的lib

项目右键,属性,链接器,输入,附加依赖项,添加 C:\Miniconda3\libs 中的如下项:

python3.lib
python38.lib

编译引用 pyd

新建源文件 test.cpp

#include <pybind11/pybind11.h>

namespace py = pybind11;

int add(int a, int b)
{
    return a + b;
}


PYBIND11_MODULE(test, m) {
    m.doc() = "....";
    m.def("foo", [](/p/d41d8cd98f00b204e9800998ecf8427e) {
        return "Hello world!";
        });
    m.def("add", &add, "function add");
}

生成pyd快捷键: CTRL + B, 文件输出位置: project\x64\Debug

生成的pyd文件修改为 test.pyd

在 python 中调用:

import test

s = test.add(1,2)
print(s) # 3

print(test.foo()) # Hello world!

使用NumPy数组

c++ 侧:

py::array_t<double>  test(int lenArray)
{
    // 定义2维数组
    py::array_t<double> test = py::array_t<double>(lenArray);
    test.resize({ 2,lenArray / 2 });

    // 定义可写入对象
    auto w_test = test.mutable_unchecked<2>();

    for (int i = 0; i < test.shape()[0]; i++) {
    	for (int j = 0; j < test.shape()[1]; j++) {
    		w_test(i, j) = i + j;
    	}
    }

    return test;
}

python 侧:

# -*- coding: utf-8 -*-
# cpp编写的函数在项目cppext 的 cppext.cpp 文件中
import sys
sys.path.append('./cppext/x64/Debug/')
import cppext

r = cppext.test(20)
print(r)    
'''
[[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.]
 [ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]]
'''

参考

使用selenium,Selenium Wire和chromedriver

centos7 下安装配置 selenium

安装 firefox , selenium

yum install firefox
conda install selenium

安装 firefox驱动 geckodriver

firefox 官方驱动下载地址: https://github.com/mozilla/geckodriver/releases

cd ~
wget https://github.com/mozilla/geckodriver/releases/download/v0.23.0/geckodriver-v0.23.0-linux64.tar.gz
tar zxvf geckodriver-v0.23.0-linux64.tar.gz
cp geckodriver /usr/local/bin

测试:

>>> from selenium import webdriver
>>> options = webdriver.FirefoxOptions()
>>> options.add_argument("--headless")
>>> options.add_argument("--disable-gpu")
>>> driver = webdriver.Firefox(firefox_options=options)
__main__:1: DeprecationWarning: use options instead of firefox_options
>>> driver.get("https://baidu.com/")
>>> driver.page_source
>>> driver.close()
>>> driver.quit()

如果没有出错,显示了网页源代码, ok! 测试成功.

相关命令

  • driver.quit():退出并关闭窗口的每一个相关的驱动程序,它还有个类似的表弟。
  • driver.close():关闭当前窗口

firefox_profile

firefox_profile = webdriver.FirefoxProfile()
firefox_profile = webdriver.FirefoxProfile()
firefox_profile.set_preference('permissions.default.image', 2)  # 禁用图片
firefox_profile.set_preference('permissions.default.stylesheet', 2)  # 禁用CSS
firefox_profile.set_preference('dom.ipc.plugins.enabled.libflashplayer.so', 'false') # 禁用 Flash
firefox_profile.set_preference('javascript.enabled', 'false') # 禁用js

driver = webdriver.Firefox(firefox_profile=firefox_profile)
driver.get('https://re.jd.com/')

参考

windows 下安装步骤类似

VPS ubuntu 安装Chrome,Selenium ,ChromeDriver

pip install selenium
cd ~
proxychains wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
sudo apt-get update && sudo apt-get install google-chrome-stable
google-chrome --version
Google Chrome 95.0.4638.69

https://chromedriver.chromium.org/downloads ,或国内镜像 https://npm.taobao.org/mirrors/chromedriver/ 下载对应版本:

wget https://npm.taobao.org/mirrors/chromedriver/95.0.4638.54/chromedriver_linux64.zip
unzip chromedriver_linux64.zip 
sudo cp chromedriver /usr/bin/chromedriver 
sudo chown root:root /usr/bin/chromedriver 
sudo chmod +x /usr/bin/chromedriver 

python 中测试:

from selenium import webdriver#下面3行代码执行后,不会打开Chrome浏览器,不会产生chromedriver.exe进程
options = webdriver.ChromeOptions()
options.add_argument('headless')
driver = webdriver.Chrome(options=options)
driver.get('https://www.baidu.com')
print(driver.page_source)
driver.quit() # 关闭driver(关闭窗口并结束chromedriver.exe进程)

参考:

python3 使用 chromedriver

查看版本chrome版本: 点击Chrome菜单“帮助”→“关于Google Chrome”,即可查看Chrome的版本号

下载chromedriver:

在Windows下,直接将chromedriver.exe文件拖到Python的Scripts目录下, 如: C:\Miniconda3\Scripts

安装 selenium: conda install selenium

在 Python3中使用:

from selenium import webdriver#下面3行代码执行后,不会打开Chrome浏览器,不会产生chromedriver.exe进程
options = webdriver.ChromeOptions()
options.add_argument('headless')
driver = webdriver.Chrome(options=options)
driver.get('https://www.baidu.com')
print(driver.page_source)
driver.quit() # 关闭driver(关闭窗口并结束chromedriver.exe进程)

错误: WebDriverException

WebDriverException: 'chromedriver' executable needs to be in PATH. Please see https://chromedriver.chromium.org/home

查看版本chrome版本: 点击Chrome菜单“帮助”→“关于Google Chrome”,即可查看Chrome的版本号

下载chromedriver:

在Windows下,直接将chromedriver.exe文件拖到Python的Scripts目录下, 如: C:\Miniconda3\Scripts

Selenium Wire

由Selenium编写的测试脚本可以像真正的用户去操作页面控件及浏览器。但是,有些时候我们需要获取后台接口返回给前端的数据,用于测试、数据绑定校验、记录日志、调试等,对于以上这种行为Selenium则无能为力。

若想捕获HTTP请求或者网络流量,我们就需要HTTP代理服务器,然后通过配置浏览器指向该代理服务器来实现。而Selenium Wire就是一个很好的解决方案,它是Python Selenium WebDriver的拓展库,能够直接访问浏览器发出的底层请求。

Selenium Wire可以与使用Selenium相同的方式编写测试脚本,并额外提供简单易用的接口行为,用于访问请求/响应头、状态代码和报文内容。官网的介绍:

Selenium Wire extends Selenium's Python bindings to give you access to the underlying requests made by the browser. You author your code in the same way as you do with Selenium, but you get extra APIs for inspecting requests and responses and making changes to them on the fly.

所以可以将 Selenium Wire 看做是加强版的 Selenium。底层部分部分依然依赖于Selenium,对Selenium进行了扩展。

安装:pip install selenium-wire

Selenium Wire 可以在测试时捕获所有HTTP/HTTPS 请求,你可以通过driver.requests属性来访问对象,该对象将所有HTTP请求存储为一个列表变量:

from seleniumwire import webdriver  # Import from seleniumwire  

# 创建火狐浏览器实例 
driver = webdriver.Firefox()  

# 访问测试网站
driver.get('https://www.google.com')  

# 访问并依次打印所有request对象
for request in driver.requests:  
    if request.response:  
    	print(  
    		request.url,  
    		request.response.status_code,  
    		request.response.headers['Content-Type'])  
driver.quit()

更多,参考:

报错 selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH

selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home

将包含 chromedriver.exe 的目录加入windows系统path,重启shell

其他

如何在 Node.js 环境安装 Selenium(英文)

Selenium 是通用的浏览器测试框架,本文介绍如何在 Node.js 里面使用它。

Testcafe 教程(英文)

<p>python库(2)</p>

Testcafe 是一个 UI 测试框架,可以在各大浏览器进行 UI 测试。相比 Puppeteer,它提供各种专门针对测试的封装好的方法。

Appium:功能测试App的框架

软件工程师(尤其是高学历的)一般都只喜欢做高大上的写代码的工作,不想做测试,不想做运维,不想做“没技术含量”的工作 — 实际上世界上没那么多有技术含量的事情让你做。

小公司一般无法奢侈地有专门的测试岗位。所以好的测试都得靠工程师自己做。比较好的practice是,架一台大电视屏幕,显示几个跟代码有关的指标 — 最重要的指标是,test coverage。这样有助于帮助团队理解test是不是有足够大得覆盖率。

昨天在微博看到Fenng在调查大家怎么做app的测试的。我就想到了Sauce Lab做的Appium。前几周他们的工程师来给talk,介绍了这个测试app的框架,支持iOS和Android。跟Selenium有点像,你可以用各种语言(python, ruby,nodejs等)来写test case,然后它会自动启动模拟器跑app、跑测试、模拟输入、模拟各种手势等。基本上,每个工程师,一人贡献几个test case,一下就能把整个团队的code base代码质量提高不少。

loguru

安装: pip install loguru

示例:

from loguru import logger  

# 使用enqueue,可以保证多线程安全、多进程安全:enqueue=True,
# 修改时间格式: format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}"
# 日志文件大小循环:rotation="20KB"
*************** to do list *****************************

log_path = 'path_to_log_file'

logger.remove(handler_id=None)  # 清除之前的设置, 相当于删除掉了向console 的默认输出, 避免向文件重复输出
logger.add(sink=log_path, enqueue=True, rotation="200KB", format="{time:MM-DD HH:mm:ss} | {message}", encoding='utf-8')


@logger.catch  # 记录异常
def func_name():
    pass

OSError: [Errno 5] Input/output error

可能的原因: 通过shell运行的脚本中有 print 语句,shell退出后,会因为 print 没有地方输出字符导致报一个 I/O 错误

解决方式:

  • 使用loguru.logger.info(info) 替代 print(info), 不再使用print语句,调试时注释掉 logger.remove(handler_id=None)
  • 注释掉 print语句
  • 通过crontab运行脚本

参考:

正文完
 
评论(没有评论)