0 引言
lua是一种语法极为灵活、扩展性极强的“胶水语言”, 在使用lua/lua capi时常常会写出一些容易出错的code. 因此,有必要建立以lua vm为基础的unit test帮助程序员及早地发现bug,提高代码的质量。为此,有三件事情需要做。
1 编译配置googletest/googlemock环境
https://stackoverflow.com/questions/13513905/how-to-set-up-googletest-as-a-shared-library-on-linux
2 编译配置lua5.0
2.1 download src file: https://www.lua.org/ftp/lua-5.0.3.tar.gz
2.2 make
2.3 write testing code:
#include <stdio.h> #include <string.h> extern "C" {///< It is very important to wrap related header files into this cracket, or you will get some error message as below. #include "mylua/lua.h" #include "mylua/lauxlib.h" #include "mylua/lualib.h" } int main(void) { char buff[256] = "print("hello world! ")"; int error; lua_State* L = lua_open(); /* opens Lua */ luaopen_base(L); /* opens the basic library */ luaopen_table(L); /* opens the table library */ luaopen_io(L); /* opens the I/O library */ luaopen_string(L); /* opens the string lib. */ luaopen_math(L); /* opens the math lib. */ while (fgets(buff, sizeof(buff), stdin) != NULL) { error = luaL_loadbuffer(L, buff, strlen(buff), "line") || lua_pcall(L, 0, 0, 0); if (error) { fprintf(stderr, "%s", lua_tostring(L, -1)); lua_pop(L, 1); /* pop error message from the stack */ } } lua_close(L); return 0; }
2.3 use g++ to build:
g++ test.c -I $LD_HOME/include -L $LD_HOME/lib -llua -llualib -o app
3 集成测试
2.1 编写luaC 类
//lua_c.hh #ifndef _LUA_C_HH_ #define _LUA_C_HH_ #include <vector> #include <string> #include <iostream> #include <cstring> extern "C" { #include "mylua/lua.h" #include "mylua/lauxlib.h" #include "mylua/lualib.h" } class LuaC { public: LuaC() { d_avr = 0.0; d_sum = 0; } void ComAvrSum(const std::vector<int>& vec); void print() { std::cout << "avr = " << d_avr << std::endl; std::cout << "sum = " << d_sum << std::endl; } double getAvr() { return d_avr; } double getSum() { return d_sum; } private: double d_avr; int d_sum; }; #endif ///< _LUA_C_HH_
//lua_c.cc #include "lua_c.hh" lua_State* InitLua() { lua_State* L = lua_open(); /* opens Lua */ luaopen_base(L); /* opens the basic library */ luaopen_table(L); /* opens the table library */ luaopen_io(L); /* opens the I/O library */ luaopen_string(L); /* opens the string lib. */ luaopen_math(L); /* opens the math lib. */ return L; } static int foo(lua_State* L) { int n = lua_gettop(L); /* number of arguments */ lua_Number sum = 0; int i; for (i = 1; i <= n; i++) { if (!lua_isnumber(L, i)) { lua_pushstring(L, "incorrect argument to function `average'"); lua_error(L); } sum += lua_tonumber(L, i); } lua_pushnumber(L, sum / n); /* first result */ lua_pushnumber(L, sum); /* second result */ return 2; /* number of results */ }; void LuaC::ComAvrSum(const std::vector<int>& vec) { lua_State* L = InitLua(); lua_register(L, "average", foo); ///< method 1: lua_register std::string buff = "avr, sum = average("; for (size_t i = 0; i < vec.size() - 1; ++ i) { buff += std::to_string(vec[i]) + ", "; } buff += std::to_string(vec[vec.size()-1]) + ")"; std::cout << "buff = " << buff << std::endl; int error; error = luaL_loadbuffer(L, buff.c_str(), strlen(buff.c_str()), "average") || lua_pcall(L, 0, 0, 0); ///< first load, and second call if (error) { fprintf(stderr, "%s", lua_tostring(L, -1)); lua_pop(L, 1); // pop error message from the stack } lua_getglobal(L, "avr"); d_avr = lua_tonumber(L, -1); lua_pop(L, 1); lua_getglobal(L, "sum"); d_sum = lua_tonumber(L, -1); lua_pop(L, 1); }
2.2 编写测试函数
// Test_Lua_C.cc
#include "gtest/gtest.h" #include "lua_c.hh" TEST(Lua_C, ComAvrSum) { LuaC aa; std::vector<int> vec; vec.push_back(33); aa.ComAvrSum(vec); aa.print(); EXPECT_EQ(33, aa.getSum()); EXPECT_EQ(33, aa.getAvr()); vec.push_back(33); aa.ComAvrSum(vec); aa.print(); EXPECT_EQ(66, aa.getSum()); EXPECT_EQ(33, aa.getAvr()); }
2.3 编译
g++ Test_Lua_C.cc lua_c.cc -I $LD_HOME/include -L $LD_HOME/lib -lgtest -lgtest_main -lpthread -llua -llualib -o app -std=c++11
running
[==========] Running 1 test from 1 test case. [----------] Global test environment set-up. [----------] 1 test from Lua_C [ RUN ] Lua_C.ComAvrSum buff = avr, sum = average(33) avr = 33 sum = 33 buff = avr, sum = average(33, 33) avr = 33 sum = 66 [ OK ] Lua_C.ComAvrSum (0 ms) [----------] 1 test from Lua_C (0 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test case ran. (0 ms total) [ PASSED ] 1 test.
Done !