Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dartの非同期コードテストについて

 Dartの非同期コードテストについて

MAO YUFENG

May 27, 2021
Tweet

More Decks by MAO YUFENG

Other Decks in Programming

Transcript

  1. Add test dependency # pubspec.yaml dev_dependencies: # If this is

    a dart package test: ^1.17.4 # If this is a flutter package flutter_test: sdk: flutter
  2. How to write test // Test target int addOne(int num)

    => num + 1; // Tests are specified using the test() function // Test assertions are made using expect() void main() { test('test add 1', () { expect(addOne(9), 10); // Or using matcher expect(addOne(9), equals(10)); }); }
  3. How to write test // Test target int addOne(int num)

    => num + 1; // Tests are specified using the test() function // Test assertions are made using expect() void main() { test('test add 1', () { expect(addOne(9), 10); // Or using matcher expect(addOne(9), equals(10)); }); }
  4. How to write test // Test target int addOne(int num)

    => num + 1; // Tests are specified using the test() function // Test assertions are made using expect() void main() { test('test add 1', () { expect(addOne(9), 10); // Or using matcher expect(addOne(9), equals(10)); }); }
  5. How to write test // Test target int addOne(int num)

    => num + 1; // Tests are specified using the test() function // Test assertions are made using expect() void main() { test('test add 1', () { expect(addOne(9), 10); // Or using matcher expect(addOne(9), equals(10)); }); }
  6. Test Future void main() { test('Test addOneAsync via completion matcher',

    () { Future<int> data = addOneAsync(9); expect(data, completion(10)); }); test('Test addOneAsync via async/await', () async { int data = await addOneAsync(9); expect(data, 10); }); }
  7. Test Future void main() { test('Test addOneAsync via completion matcher',

    () { Future<int> data = addOneAsync(9); expect(data, completion(10)); }); test('Test addOneAsync via async/await', () async { int data = await addOneAsync(9); expect(data, 10); }); }
  8. Test Future void main() { test('Test addOneAsync via completion matcher',

    () { Future<int> data = addOneAsync(9); expect(data, completion(10)); }); test('Test addOneAsync via async/await', () async { int data = await addOneAsync(9); expect(data, 10); }); }
  9. Test Future error void main() { test('Test future error via

    throwsException matcher', () { expect(willThrowException(), throwsException); }); }
  10. Test hidden async operations // Test target class Counter {

    var value = 9; void addOne() { Future(() => value = value + 1); } }
  11. Test hidden async operations void main() { test('test counter addOne',

    () { final counter = Counter(); counter.addOne(); // Assertion will fail, counter.value is still 9. expect(counter.value, 10); }); } Assertion時点に、addOne中のFuture タスクはまだ実行されていません
  12. void main() { test('test counter addOne', () { final counter

    = Counter(); counter.addOne(); expect(counter.value, 10); }); } Test hidden async operations
  13. void main() { test('test counter addOne', () async { final

    counter = Counter(); counter.addOne(); // Let event loop handling the addOne task before assertion await Future(() {}); expect(counter.value, 10); }); } Assertionする前に、Event loopの タスク処理を待ちます Test hidden async operations
  14. Test hidden async operations void main() { test('test counter addOne',

    () async { final counter = Counter(); counter.addOne(); // Let event loop handling the addOne task before assertion await pumpEventQueue(); expect(counter.value, 10); }); } Assertionする前に、Event loopの タスク処理を待ちます
  15. Test Stream void main() { test('test stream', () { final

    stream = Stream.fromIterable(['CA', 'Base', 'Next']); expect(stream, emitsInOrder(['CA', 'Base', 'Next', emitsDone])); }); } emitsXxxの命名のような、 他のStreamMatecherもあります
  16. Test Stream interactively class Counter { var _value = 0;

    final _valueStream = StreamController<int>.broadcast(); // Test target Stream<int> get valueStream => _valueStream.stream; void addOne() { _value = _value + 1; _valueStream.add(_value); } }
  17. Test Stream interactively void main() { test('test counter stream', ()

    { final counter = Counter(); counter.addOne(); counter.addOne(); counter.addOne(); // Assertion fail 😵 expect(counter.valueStream, emitsInOrder([1, 2, 3])); }); } Assertionする時点、値もうすでに 流れていました
  18. Test Stream interactively void main() { test('test counter stream', ()

    { final counter = Counter(); // Assert before any opertions expect(counter.valueStream, emitsInOrder([1, 2, 3])); }); }
  19. Test Stream interactively void main() { test('test counter stream', ()

    { final counter = Counter(); // Assert before any opertions expect(counter.valueStream, emitsInOrder([1, 2, 3])); }); } Streamの値が変化する前に Assertionします
  20. Test Stream interactively void main() { test('test counter stream', ()

    { final counter = Counter(); // Assert before any opertions expect(counter.valueStream, emitsInOrder([1, 2, 3])); counter.addOne(); counter.addOne(); counter.addOne(); }); } Streamの値が変化する前に Assertionします
  21. Recap • Future/Stream のテストには test package が提供する Matcher を使いましょう •

    隠された非同期処理をテストするには pumpEventQueue で処理を待ちましょう • 先に expect を呼んで、 後で発生する非同期処理をテストしましょう