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

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

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

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

Avatar for MAO YUFENG

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 を呼んで、 後で発生する非同期処理をテストしましょう