如何在Linux下建立包含lua vm的unit test framwork

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 !

原文地址:https://www.cnblogs.com/ghjnwk/p/15021182.html