如何制作简洁的测试用例?

时间:2017-04-21 18:37:51

标签: unit-testing

所以我有一个分配Manager和Worker之间关系的函数。 具有以下要求。作为(Admin,Manager和Worker)登录有三个角色。

  1. 在任何时候,如果经理或工人被禁用 - 抛出错误("已禁用")
  2. 无法添加已分配的工作人员 - 抛出错误("拥有")
  3. 管理员可以在遵守1.和2.规则的情况下,为任何工作人员添加任何经理的任何关系。
  4. 经理只能在遵守1.和2.规则的情况下为自己添加工人。
  5. 工作人员无法添加任何内容。
  6. 这是一个非常简单的要求,但是当我概述测试内容时,我对这么多可能的测试用例感到困惑,以确保完全覆盖直到感觉多余。例如,

    作为管理员

    • 将无主经理分配给无主工人 - 成功
    • 将无主经理分配给所有员工 - 失败
    • 将所有经理分配给无主工人 - 成功
    • 将所有经理分配给所有员工 - 失败

    • 将无主经理(已禁用)分配给无主工人 - 失败

    • 将无主经理(已禁用)分配给所有员工 - 失败
    • 将自有经理(已禁用)分配给无主工人 - 失败
    • 将所有经理(已禁用)分配给所有员工 - 失败

    • 将无主经理分配给无主工人(已禁用) - 失败

    • 将无主经理分配给所有员工(已禁用) - 失败
    • 将自有经理分配给无主工人(已禁用) - 失败
    • 将所有经理分配给所有员工(已禁用) - 失败

    • 将无主管理者(已禁用)分配给无法拥有的工作人员(已禁用) - 失败

    • 将无主经理(已禁用)分配给拥有的工作人员(已禁用) - 失败
    • 将自有经理(已禁用)分配给无主工作人员(已禁用) - 失败
    • 将拥有的经理(已禁用)分配给拥有的工作人员(已禁用) - 失败

    作为经理

    • 将无主经理(自己)分配给无主工人 - 成功
    • 将无主经理(自己)分配给所有员工 - 失败
    • 将拥有的经理(自己)分配给无主工人 - 成功
    • 将所有经理(自己)分配给所有员工 - 失败
    • 将无主经理(其他)分配给无主工人 - 失败
    • 将无主经理(其他)分配给所有员工 - 失败
    • 将拥有的经理(其他)分配给无主工人 - 失败
    • 将所有经理(其他)分配给所有员工 - 失败

    • 将无主经理(自我禁用)分配给无主工人 - 失败

    • 将无主经理(自我禁用)分配给所有员工 - 失败
    • 将自有经理(自我禁用)分配给无主工人 - 失败
    • 将拥有的经理(自我禁用)分配给所有员工 - 失败
    • 将无主管理员(其他已禁用)分配给无主工人 - 失败
    • 将无主经理(其他已禁用)分配给所有员工 - 失败
    • 将自有经理(其他残疾人)分配给无主工人 - 失败
    • 将所有经理(其他已禁用)分配给所有员工 - 失败

    • 将无主经理(自己)分配给无主工人(已禁用) - 失败

    • 将无主经理(自己)分配给所有员工(已禁用) - 失败
    • 将拥有的经理(自己)分配给无主工人(已禁用) - 失败
    • 将拥有的经理(自己)分配给所有员工(已禁用) - 失败
    • 将无主经理(其他)分配给无主工人(已禁用) - 失败
    • 将无主经理(其他)分配给所有员工(已禁用) - 失败
    • 将拥有的经理(其他)分配给无主工人(已禁用) - 失败
    • 将所有经理(其他)分配给所有员工(已禁用) - 失败

    • 将无主经理(自我禁用)分配给无主工人(已禁用) - 失败

    • 将自有经理(自我禁用)分配给所有员工(已禁用) - 失败
    • 将自有经理(自我禁用)分配给无主工人(已禁用) - 失败
    • 将拥有的经理(自我禁用)分配给所有员工(已禁用) - 失败
    • 将无主管理员(其他已禁用)分配给无法拥有的工作人员(已禁用) - 失败
    • 将未拥有的经理(其他已禁用)分配给拥有的工作人员(已禁用) - 失败
    • 将自有经理(其他已禁用)分配给无主工人(已禁用) - 失败
    • 将拥有的经理(其他已禁用)分配给拥有的工作人员(已禁用) - 失败

    您可以看到测试作为工作人员登录的位置。我希望这能说明测试用例的冗长程度。在这种情况下,开发人员通常会做些什么来制作具体而简洁的测试用例?

    function addUser(login, managerId, workerId) {
       if (login.accountType === "Worker" || login.accountType === "Manager" && login.Id !== managerId) {
              throw utils.permissionError;
       }
       try {
          const manager = database.one(Users.getActiveManagerById, managerId); // if no manager return method will throw error
          const worker = database.one(Users.getActiveWorkerById, workerId); // if no worker return method will throw error
          const relationship = database.one(UserRelationships.addUserRelationship, managerId, workerId);
          return "Success"
       } catch (e) { 
          return "Fail"
       }
    }
    

    更新 扩展蜂蜜的答案,

    我认为应该在不考虑功能实现的情况下编写测试是错误的吗?如果你看一下函数的代码,那么测试会偏向于实现吗?

    我只是在想,尽管缺乏覆盖,但编写错误的代码是否有可能通过所有测试。我希望测试给出任何函数,测试确保传递意味着函数完全有效。

    例如在

    testAdminAuthority :您不再需要考虑规则1& 2。

    编写错误的代码

    if (login.accountType !== "Admin") { //test disable }
    

    然后在这种情况下,规则1和2没有机会启动,管理员可以分配禁用的经理或残疾工人。

    如果我列出所有的排列,这种方式无论函数如何编写,都能确保考虑所有情况?

    许多其他观点可能会被故意阻碍但仍然有效。 并不是我想故意破坏任何代码/逻辑。我即将对代码进行大规模重构,并且我希望在重构完成后进行测试以覆盖功能。

1 个答案:

答案 0 :(得分:1)

  
      
  1. 在任何时候,如果经理或工人被禁用,则抛出错误(“已禁用”)
  2.   
  3. 无法添加已分配的工作人员 - 抛出错误(“拥有”)
  4.   
  5. 管理员可以在遵守1.和2.规则的情况下,为任何工作人员添加任何经理的任何关系。
  6.   
  7. 经理只能在遵守1.和2.规则的情况下为自己添加工人。
  8.   
  9. 工作人员无法添加任何内容。
  10.   

根据我的理解,您只需要上述5个测试用例,如果您的每个单元都经过测试,那么您不再需要测试这两个单元如何协同工作,那就是为什么它被称为单位 ...测试。

假设您已经编写了避免这些情况所需的所有代码,那么您的测试将类似于:

  1. testDisabledusers:说你有一群残疾工人和另一位残疾经理...... 如果您的用户已选择这些...那么您的测试将是'断言,如果没有抛出正确的错误,例如您的消息将是“用户已停用,无法分配”'this
  2. 之类的内容
  3. testAssignedWorkers:与测试1相同的逻辑
  4. testAdminAuthority:您不再需要考虑规则1& 2,你已经测试过了。虽然我实际上猜测这个测试是,但是:只有 admin 可以将任何manger添加到worker关系(其他管理员只能添加到自己)。所以要纯粹测试一旦他们将一个工人添加到经理那么它实际上是否被分配 - 如果他们曾经试图分配一个被禁用的经理/工人或指定的工人那么你的单元测试1& 2将开始......在本次测试中无需重新覆盖。
  5. testManagerRestriction:如果您的经理从其他经理中选择了...那么您的测试将是'断言,如果没有抛出正确的错误,例如你的信息将是“我们等待一分钟,你不是他的经理,不能做到!”'再次像this那样。
  6. testWorkerRestriction:与上述相同,只是它应该与其相关的方法。
  7. (记得给你的测试一个合适的名字,或许你可以提出更好的名字)