代码之家  ›  专栏  ›  技术社区  ›  josefx

重构测试代码的干净方法

  •  0
  • josefx  · 技术社区  · 15 年前

    背景 :
    我目前正在为网络协议的客户端编写测试用例。作为测试的一部分,我必须模拟来自服务器的几个不同的预期和意外响应(错误的头、连接丢失、意外消息、超时)。

    我的问题
    当前实施分为几个部分:

    • 包含测试用例所有地址的枚举
    • 包含作为静态函数的所有测试的类测试
    • 将函数名映射到相应enum+\u FUNC的多个定义
    • 以地址、函数和名称作为参数的包装类
    • 返回包装类对象列表的方法,每个测试用例一个对象

    对于收到的每条消息,服务器都会检查测试用例列表,并执行与地址对应的测试用例,或者返回默认响应。
    问题 :
    这个实现要求我为每个新的测试用例更新至少五个不同的位置,并且类测试增长得相当快。有没有重构它的好方法?
    :(此代码不是有效的c++)

    enum TestAddress
    {
       TEST_CONNECTION_BREAKDOWN = 0x100,
       TEST_ALL_IS_GOOD = 0x101,
    }
    
    
    class Wrapper : AbstrTestCase  //AbstrTestCase requires applies and test implementations
    { 
    typedef testFun;
    Wrapper(TestAddress addr,testFun func,string name)
    boolean applies(int ad,...){return addr == ad;}
    int test(...){return func(...);}
    }
    class Test
    {
    static int testConnectionBreakDownFunc (...)
    static int testAllIsGoodFunc(...)
    }
    #define TEST_CONNECTION_BREAKDOWN_FUNC Test::testConnectionBreakDownFunc
    #define TEST_ALL_IS_GOOD_FUNC Test::testAllIsGoodFunc
    
    list<AbstrTestCase*> GetTests()
    {
       list<AbstrTestCase*> tlist;
       tlist.push_back(new Wrapper(TEST_ALL_IS_GOOD,TEST_ALL_IS_GOOD_FUNC,"TEST_ALL_IS_GOOD"));
       ...
       tlist.push_back(new Wrapper(TEST_CONNECTION_BREAKDOWN,TEST_CONNECTION_BREAKDOWN_FUNC,"TEST_CONNECTION_BREAKDOWN_FUNC"));
       return tlist;
    }
    

    相关:我上一次至少清理GetTests()中代码的atemp是对包装器参数的额外定义

    #define WRAP_ARGS(N) N,N##_FUNC,#N
    tlist.push_back(new Wrapper(WRAP_ARGS(TEST_CONNECTION_BREAKDOWN));
    #undef WRAP_ARGS(N)
    

    虽然它会使代码看起来更干净,但它只会隐藏问题

    1 回复  |  直到 15 年前
        1
  •  0
  •   piotr    15 年前

    我和你有过类似的问题。我通常采用的方法是通过一个脚本来管理它,以便将代码自动添加到不同的位置。注释标记脚本处理文件的点,因此不需要编写复杂的解析器。比如:

    /* automatic code insertion point. Don't remove this comment */