2017-05-05 97 views
1

我正在为我工​​作的产品编写一个执行单元测试的迷你框架。我希望尽可能无缝地发布和管理测试数据。使用Mocha,使用After()挂钩可以轻松安排测试数据清理。Javascript摩卡时间表一次测试数据清理

您可以将单个测试包装在describe()块中,并使用该块的Before/After方法,但是如果可能,我宁愿避免这种情况。

您可以将清理功能传递给afterEach,它专门针对测试中填充的数据。虽然这只会对一次清理而言是必要的,但这样做似乎很笨拙。

是否有可能在一次测试中生成测试数据,仅仅是为了测试,还安排了与Mocha一起进行清理?

+0

1.您是否必须生成单独的文件?只要您的测试数据具有可由内存管理的大小,您就可以轻松编写测试数据生成功能。 2.你能否详细说明“只需要一次清理”的含义? 'afterEach'有什么问题? –

+0

为了更加清楚,我的测试数据使用Knex填充到数据库中。我希望测试能够从助手请求数据并让他们填充数据库,然后清理它。因此,如果一个测试块向表中插入两个条目,那么在测试运行之后,应该删除这两个条目。我可以使用它们的主键来跟踪它们并以有针对性的方式清理它们。我可以在AfterEach之后这样做,但它会在每次测试之后运行,而不是一次性清理。 – Akron

+0

如果你想测试读/写,我会建议一个模拟工具,比如优秀的['mock-knex'](https://www.npmjs.com/package/mock-knex)。或者你可以很容易地编写你自己的模拟数据库,它实现了你正在测试的方法并将条目存储在内存中。 –

回答

0

当然,只是在测试本身中运行你的代和清理。如果它是异步的,则可以使用done回调使其等待,直到它被调用。

mocha.setup('bdd'); 
 
describe('suite', function() { 
 
    function getData() { 
 
    // Simulate asynchronous data generation 
 
    console.log('grabbing data'); 
 
    return new Promise((resolve, reject) => { 
 
     setTimeout(() => resolve(100), 500); 
 
    }); 
 
    } 
 

 
    function cleanup() { 
 
    // Simulate asynchronous cleanup 
 
    console.log('cleaning up...'); 
 
    return new Promise((resolve, reject) => { 
 
     setTimeout(resolve, 500); 
 
    }); 
 
    } 
 

 
    it('should do generation and clean up', function(done) { 
 
    // Generate some data 
 
    getData() 
 
     .then(data => { 
 
     // Test the data 
 
     if (data !== 100) { 
 
      throw new Error('How?!'); 
 
     } 
 

 
     console.log('test passed'); 
 

 
     // Cleanup 
 
     return cleanup(); 
 
     }) 
 
     .then(_ => { 
 
     // Use done() after all asynchronous work completes 
 
     console.log('done cleaning'); 
 
     done(); 
 
     }) 
 
     .catch(err => { 
 
     // Make sure it cleans up no matter what 
 
     cleanup().then(_ => console.error(err)); 
 
     }); 
 
    }); 
 
}); 
 
mocha.run();
<script src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script> 
 
<div id="mocha"></div>

+0

这可能是最好的方法。我想避免在测试结束时明确地调用清理方法。我已经在describe()级别的测试数据中自动安排清理。开发人员可能会忘记在单个测试中明确清除它,因为这是不同的,但这是一个很好的方法。 – Akron

+0

@Akron尽管如此,要么指定需要清理的特定测试,要么只是运行一般清理并希望最好。据我所知,这是关于它的结果。无论如何,你需要标记一个测试清理*以某种方式*所以总有可能有人忘记清理它。 –

0

我想测试后清理是一般问题,因为清理一致性保证不是很强,即是清理功能保证运行?可能不会。如果不确定是否会进行清理,那么很可能使下一次测试处于不一致的状态。我认为这是很好做的尝试,但你可以通过防止故障:

  • 清理/建立DB状态的每个测试
  • 的摧毁世界,让每个测试具有一致的状态之前(可以通过执行来实现您在交易环境中的测试并在每次测试后回滚交易,并且至少从未进行交易)
  • 测试创建唯一数据。通过利用独特的数据,您还可以并行运行测试,因为它允许多个不同的测试具有独立的数据库视图。如果每个测试将自己的数据,你只需要担心在每个测试运行

上述的开始置备整个数据库,如果你能包住您的测试在一个事务是快如闪电, (像Django和Rails这样的web框架可以做到这一点,而且速度非常快,并且使得测试/ db状态非常容易推理)