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 下安装步骤类似
- 安装 selenium
- 从 http://www.firefox.com.cn/ 下载安装最新版 firefox
- 从 https://github.com/mozilla/geckodriver/releases 下载 firefox驱动, 解压到某个文件夹, 并将文件夹路径加入到系统环境变量的 path 中
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进程)
参考:
- How to Install Chrome browser In Linux or Ubuntu VPS
- How to Setup Selenium with ChromeDriver on Ubuntu 20.04 & 18.04
python3 使用 chromedriver
查看版本chrome版本: 点击Chrome菜单“帮助”→“关于Google Chrome”,即可查看Chrome的版本号
下载chromedriver:
- 淘宝镜像: http://npm.taobao.org/mirrors/chromedriver/
- google官方: https://chromedriver.chromium.org/downloads
在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:
- 淘宝镜像: http://npm.taobao.org/mirrors/chromedriver/
- google官方: https://chromedriver.chromium.org/downloads
在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 教程(英文)
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运行脚本
参考: