zoukankan      html  css  js  c++  java
  • 如何在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 !

  • 相关阅读:
    【题解】国家集训队礼物(Lucas定理)
    【题解】佳佳的斐波那契数列(矩阵)
    【题解】Zap(莫比乌斯反演)
    HNOI2019爆零记
    Emacs配置
    【题解】Journeys(线段树优化连边)
    一直没有敢发的NOIP2018游记
    【题解】Digit Tree
    【题解】BZOJ3489 A Hard RMQ problem(主席树套主席树)
    【题解】大括号
  • 原文地址:https://www.cnblogs.com/ghjnwk/p/15021182.html
Copyright © 2011-2022 走看看