unity-lua单元测试

unity-lua单元测试


前篇

这里说的单元测试并不是真正意义上得单元测试, 只是为了开发中能不重启进程, 动态执行一些测试代码, 不然有些测试重现场景可能会比较耗时, 因此就需要有一种功能可以动态执行一些测试代码来验证是否能达到预期或者调试 bug.

这里是基于 unity 和 tolua 的实现, 其他引擎/其他脚本语言 (如: Python) 的话思路是一样.


步骤

核心就是重写 lua 全局函数, 然后执行 函数

  1. 扩展编辑器

    1. 读取 lua 脚本, 使用正则解析捕获到 要执行的方法, 如:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      private void Refresh() {
      EditorUtils.Assert(File.Exists(mCustomLuaPath), "--- 找不到文件: {0}", mCustomLuaPath);
      string txt = Utils.ReadAllTextFromFile(mCustomLuaPath);
      MatchCollection mthArr = new Regex(@"function\s+gDebugCustom.(\w+).*?\(").Matches(txt); // 正则捕获
      if (mthArr.Count == 0) {
      Debug.LogFormat("<color=#ff0000>--- 捕获方法失败</color>");
      return;
      }

      mFuncArr = new List<string>();
      for (int i = 0; i < mthArr.Count; i++) {
      mFuncArr.Add(mthArr[i].Groups[1].Value.Trim());
      }
      }
    2. 捕获的的方法 mFuncArr 绘制到 editor 中

    3. 添加执行 lua 的代码

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
              public void CallCustomLua(string luaFile, string funcName) {
      if (!EditorApplication.isPlaying) {
      EditorUtility.DisplayDialog("错误", "只能在运行时使用", "Ok");
      EditorUtils.Assert(false, "只能在运行时使用");
      }

      GameObject go = GameObject.Find("GameMgr");
      if (go == null) {
      EditorUtility.DisplayDialog("错误", "找不到 GameMgr", "Ok");
      EditorUtils.Assert(false, "找不到 GameMgr");
      }

      if (luaFile == null) {
      return;
      }

      GameMgr.CallLuaFunction("Debug_ExecCustomLua", luaFile, funcName);
      }

      2. lua 中添加一个全局函数, 执行动态代码

      ```lua
      -- 动态执行 自定义 lua 文件调试
      function Debug_ExecCustomLua(luaFile, funcName)
      local ok = xpcall(function()
      gAssert(Utils.IsFileExist(luaFile), "--- 找不到lua 文件, path: {0}", luaFile)
      dofile(luaFile) -- 加载动态代码
      gAssert(gDebugCustom, "--- 找不到全局 table: gDebugCustom")
      gAssert(type(gDebugCustom[funcName]) == "function", "--- 找不到 gDebugCustom.{0} 方法", funcName)

      gDebugCustom[funcName]()
      end, __G__TRACKBACK__)
      if ok then
      gLog("<color=#00ff00ff>--- gDebugCustom.{0} success!</color>", funcName)
      else
      gLog("<color=yellow>--- gDebugCustom.{0} execute fail!</color>", funcName)
      end
      end
  2. 添加 单元测试 lua 文件, 如: custom_unittest.lua , 里面就是需要动态执行的逻辑

    1
    2
    3
    4
    5
    6
    7
    8
    9
    gDebugCustom = gDebugCustom or {}

    function gDebugCustom.Test001()
    gLog("--- Test001")
    end

    function gDebugCustom.Test002()
    gLog("--- Test002")
    end
  3. done.

    测试一下, 在 editor 中刷新一下方法, 然后执行