虎視眈々と

Flutter × Firebaseを研究するアプリエンジニア

Flutterでテストを書く

今回はFlutterでテストを書く方法について書いていきたいと思います。

テストについては公式サイトにもまとめられています。

flutter.io

Flutterではテスト用のライブラリのセットアップをしなくても利用できます。

テストを書く前に

テストを書く前に、ほぼ全てのプラットフォームに言えることですが、 Viewロジック は明確に分けるために 何かしらのアーキテクチャを導入しましょう。

FlutterではBLoC(Business Logic Component) が有名ですので、この記事ではBLoCで書かれたプロジェクトに対してテストを追加していきます。


自分が以前にBlocに関する記事を書いたのでまだ呼んでない方はこちらをご覧ください。 この記事ではここで書かれたカウントアップのソースコードを使って説明していきます。

www.shogogeek.com

カウントアップアプリを修正する

テストを書くためにカウントアップアプリを少しだけロジックを追加します。

追加する仕様は 「カウントアップしていって3の倍数のときだけFlutterと表示する」という内容です。

  • IncrementBloc.dart
import 'dart:async';

import 'package:bloc_sample_app/BlocProvider.dart';

class IncrementBloc implements BlocBase {

  int _counter;

  // handle controller
  StreamController<String> _counterController = StreamController<String>();
  StreamSink<String> get _inAdd => _counterController.sink;
  Stream<String> get outCounter => _counterController.stream;

  // handle view action
  StreamController<int> _actionController = StreamController<int>();
  StreamSink<int> get incrementCounter => _actionController.sink;

  IncrementBloc() {
    _counter = 0;
    _actionController.stream.listen(_handleLogic);
  }

  void _handleLogic(data) {
    _counter += 1;
    _inAdd.add(isMultiplesThree(_counter));
  }

  String isMultiplesThree(int counter) {

    if (counter % 3 == 0) {
      return "Flutter";
    }

    return counter.toString();
  }

  @override
  void dispose() {
    _counterController.close();
    _actionController.close();
  }
}
import 'dart:async';

import 'package:bloc_sample_app/BlocProvider.dart';
import 'package:bloc_sample_app/minimum/IncrementBloc.dart';
import 'package:flutter/material.dart';


class MinimumStateless extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider<IncrementBloc>(
      bloc: IncrementBloc(),
      child: Minimum(),
    );
  }
}

class Minimum extends StatefulWidget {
  @override
  _MinimumState createState() => new _MinimumState();
}

class _MinimumState extends State<Minimum> {
  int counter = 0;

  @override
  Widget build(BuildContext context) {
    final IncrementBloc bloc = BlocProvider.of<IncrementBloc>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text("最小のBLoC"),
      ),
      body: Center(
        child: StreamBuilder<String>(
            stream: bloc.outCounter,
            initialData: counter.toString(),
            builder: (context, snapshot) {
              return Text("${snapshot.data}");
            }),
      ),
      floatingActionButton:
          FloatingActionButton(
              child: Icon(Icons.add),
              onPressed: () {
                bloc.incrementCounter.add(counter);
              }),
    );
  }
}

f:id:superman199323:20180915101212g:plain

テストを書く

やってここでテストを書いていきましょう。 テストを書くメソッドは isMultiplesThree です。

テストコードの置き場所は test パッケージの下に置きましょう。

f:id:superman199323:20180915101829p:plain

テストの下に置いたら、一旦下記のコードを書いてテストを成功させましょう。

import 'package:flutter_test/flutter_test.dart';

void main() {

  test("3の倍数なテスト", () {
    expect(true, true);
  });
}

これが成功したらテストを書いていきます。

[f:id:superman199323:20180915102407p:plain]import 'package:bloc_sample_app/minimum/IncrementBloc.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {

  IncrementBloc bloc;
  setUp(() async {
    bloc = IncrementBloc();
  });

  test("3の倍数なテスト", () {
    expect(bloc.isMultiplesThree(33), "Flutter");
  });

  test("3の倍数でないテスト", () {
    expect(bloc.isMultiplesThree(500), "500");
  });
}

これでテストが成功したらおっけーです。

コマンドラインからテスト

ちなみにコマンドラインからテストも実行できます。 コマンドラインからテストを実行すると全てのテストが実行できるのでCIのときとかで便利ですね。

flutter test