自动化测试中Python与C/C++的混合使用
From:?http://hi.baidu.com/sacmelody/blog/item/cf3ee7088d2112f036d12289.html
背景
項目的自動化測試中已經使用了基于Python腳本的框架,自動化過程中最關鍵的問題就是如何實現樁模塊。運用 Python 強大的功能,實現任何樁模塊都是可能的,但是是否必須完全使用 Python 實現模塊邏輯,成本是一個決定性因素。在樁模塊邏輯簡單的情況下,使用 Python 模擬模塊邏輯不但使自動化測試的結構清晰,也具有更好的靈活性,但是如果樁模塊邏輯復雜,實現起來可能要耗費很大的成本,也容易由于樁模塊邏輯與實際不符導致測試結果不可信。在這種情況下,如果能夠借用 RD 開發的某些代碼段 / 庫,將會對測試自動化帶來很多效益。
另外,在Python 中調用 C/C++ 代碼的方法也可能應用于 C/C++ 庫的測試中,這種測試方法的可行性還有待研究。
以下總結出幾種在Python 中調用 C/C++ 代碼的方法
使用ctypes 模塊調用 C 動態庫
從Python2.5 開始, Python 開始提供 ctypes 模塊來提供對 C 語言編譯的動態庫文件的調用。注意,? 這里特指C 的動態庫? ,用C++ 編譯的動態庫 ctypes 雖然能夠加載,但調用時的函數名已經由于 C++ 的重載特性被加以修改,難以調用。 使用 ctypes 調用 C 動態庫的好處在于不用進行額外的開發,可以直接使用編譯好的動態庫。 ctypes 提供了完整的 C 類型封裝,也支持自定義類型,大大減少在調用過程中的工作量。 ctypes 的使用很簡單,只需熟悉 python 封裝與 C 中的對應關系即可。以下用一個簡單的例子來說明:
from? ctypes? import? * #導入ctypes模塊
libc = cdll.LoadLibrary("libc.so.6") #加載libc動態庫
str? = c_char_p(' Hello World! ') #使用char *在ctypes中的對應封裝c_char_p,相當于char* str=”Hello World!”
libc.printf(“yell: %s\n”,? str ) #調用printf函數
ctypes的功能當然遠不止這些,有興趣的同學可以參考這里 http://docs.python.org/library/ctypes.html
使用Python 的擴展( Extending )機制
ctypes很方便地可以調用 C 的動態庫,但是對 C++ 編譯的動態庫,調用起來很困難。這種情況利用 Python 的 Extending 機制就可以解決。 Python 提供了一套完整的框架來使用 C/C++ 編寫擴展庫,可以很靈活的開發 C++ 擴展模塊。這種方法的缺點是工作量比較大,需要為每一個方法編寫接口,這里不做詳細介紹,可以參考: http://docs.python.org/extending/extending.html#writing-extensions-in-c
那么有什么辦法可以高效的調用C++ 動態庫呢,答案是 SWIG 。
使用SWIG 生成擴展模塊
上面提到了Python 的擴展機制,缺點是工作量比較大,這里介紹一個工具 SWIG 。 SWIG 是一種簡化腳本語言與 C/C++ 接口的開發工具,通過包裝和編譯 C 語言程序來達到與腳本語言通訊目的的工具。它正是基于 Python 的擴展機制,自動生成接口文件,再編譯成可以被 Python 調用的動態庫擴展模塊。
使用SWIG 生成擴展模塊分為以下幾步:
假設有如下文件
swig_ex.cpp 需要轉換成擴展庫的原始代碼,包含一個int fact(int) 函數
swig_ex.h? 原始代碼的頭文件
swig_ex.i SWIG描述文件
swig_ex.i是一個描述文件,有 SWIG 自己的語法,比較簡單,內容如下:
| %module swig_ex %{ ??? #define SWIG_FILE_WITH_INIT ??? #include "swig_ex.h" %} int fact(int n); |
再寫一個Makefile 來把這些文件編譯成動態庫 :
| all: swig_ex.o swig_ex_wrap.o _swig_ex.so swig_ex.o: swig_ex.cpp swig_ex.h #編譯源文件 ?? g++ -fPIC -c swig_ex.cpp swig_ex_wrap.o: swig_ex.i swig_ex.o #根據 SWIG 描述文件 (.i) 生成接口文件 (.cxx) ,再編譯之 ?? swig -c++ -python swig_ex.i ?? g++ -O2 -fPIC -c swig_ex_wrap.cxx -I/home/work/linyi/autoframe/tool/python/include/python2.6/ _swig_ex.so: swig_ex_wrap.o #將目標文件打包成動態庫 ?? g++ -shared swig_ex.o swig_ex_wrap.o -o _swig_ex.so .PHONY: clean clean: ?? rm -rf swig_ex_wrap.* swig_ex.py _swig_ex.so |
編譯好以后會有一個so 和 py 文件,寫一個 setup.py 把他們安裝到 python 目錄就可以和其他模塊一樣被 python 調用了:
| Import swig_ex swig_ex.fact(10) |
參考文檔地址:http://www.swig.org/Doc1.3/SWIGDocumentation.html
原始但有效的方法
除了上面這些方法,在Python 中借用 C/C++ 代碼最原始有效的方法就是將代碼編譯成可執行程序,從 Python 里用 Popen 方法來調用獲取輸出。這種方法簡單有效,缺點是不夠靈活,有比較大的局限性,不過在很多情況下也已經足夠了。
| pipe = os.popen('./tool –a %s –b %s' % (“hello”, “world”)) re = pipe.read() |
其他方法
以上這些方法基本上已經能滿足Python 調用 C/C++ 的需求了,此外還有一些方法,例如使用 Boost.Python ,使用 Pyrex ,這些方法都能提供 Python 與 C/C++ 的交互。
總結
在Python 中引用 C/C++ 模塊的方法較多,根據需要從中選擇恰當的方法可以減少很多工作量。
在Python 中引用 C/C++ 模塊彌補了 Python 腳本測試框架的很多不足,在提高代碼復用率的同時,模塊的性能也大大提高。
總結
以上是生活随笔為你收集整理的自动化测试中Python与C/C++的混合使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 已知思科ASA设备漏洞仍在其新版本中存在
- 下一篇: 两种土壤类型数据的简介、下载教程