報奨金情報: 次の場合に回答を受け入れます。
- 線に沿ったものではありません
do this instead
- コードサンプルはほとんど変更されていません
- ドキュメントからの引用だけでなく、成功したテストを作成する
- 余分なパッケージは必要ありません
[編集: 07/02/21] Discord のフラッター コミュニティに関する Miyoyo#5957 に従い
@iapicca Convert widget position to global, get width height, add both, and see if the resulting bottom right position is on screen?
、次の回答を参照として使用します。
以下のコードサンプルを指定してください(Dartpadでも実行可能)
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
final _testKey = GlobalKey();
const _fabKey = ValueKey('fab');
final _onScreen = ValueNotifier<bool>(true);
void main() => runApp(_myApp);
const _myApp = MaterialApp(
home: Scaffold(
body: MyStage(),
floatingActionButton: MyFAB(),
),
);
class MyFAB extends StatelessWidget {
const MyFAB() : super(key: const ValueKey('MyFAB'));
@override
Widget build(BuildContext context) => FloatingActionButton(
key: _fabKey,
onPressed: () => _onScreen.value = !_onScreen.value,
);
}
class MyStage extends StatelessWidget {
const MyStage() : super(key: const ValueKey('MyStage'));
@override
Widget build(BuildContext context) => Stack(
children: [
ValueListenableBuilder(
child: FlutterLogo(
key: _testKey,
),
valueListenable: _onScreen,
builder: (context, isOnStage, child) => AnimatedPositioned(
top: MediaQuery.of(context).size.height *
(_onScreen.value ? .5 : -1),
child: child,
duration: const Duration(milliseconds: 100),
),
),
],
);
}
テストしたいのはウィジェットですoff screen
ここまでのテストコードは次のとおりです
void main() {
testWidgets('...', (tester) async {
await tester.pumpWidget(_myApp);
final rect = _testKey.currentContext.findRenderObject().paintBounds;
expect(tester.getSize(find.byKey(_testKey)), rect.size,
reason: 'size should match');
final lowestPointBefore = rect.bottomRight.dy;
print('lowest point **BEFORE** $lowestPointBefore ${DateTime.now()}');
expect(lowestPointBefore > .0, true, reason: 'should be on-screen');
await tester.tap(find.byKey(_fabKey));
await tester.pump(const Duration(milliseconds: 300));
final lowestPointAfter =
_testKey.currentContext.findRenderObject().paintBounds.bottomRight.dy;
print('lowest point **AFTER** $lowestPointAfter ${DateTime.now()}');
expect(lowestPointAfter > .0, false, reason: 'should be off-screen');
});
}
および生成されたログ
00:03 +0: ...
lowest point **BEFORE** 24.0 2021-02-07 16:28:08.715558
lowest point **AFTER** 24.0 2021-02-07 16:28:08.850733
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure object was thrown running a test:
Expected: <false>
Actual: <true>
When the exception was thrown, this was the stack:
#4 main.<anonymous closure> (file:///home/francesco/projects/issue/test/widget_test.dart:83:5)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)
...
This was caught by the test expectation on the following line:
file:///home/francesco/projects/issue/test/widget_test.dart line 83
The test description was:
...
════════════════════════════════════════════════════════════════════════════════════════════════════
00:03 +0 -1: ... [E]
Test failed. See exception logs above.
The test description was: ...
00:03 +0 -1: Some tests failed.
私のアプローチが正しいかどうかはわかりませんが、印刷物の時間はそれを示唆しています
lowest point **BEFORE** 24.0 2021-02-07 16:28:08.715558
lowest point **AFTER** 24.0 2021-02-07 16:28:08.850733
await tester.pumpAndSettle(Duration(milliseconds: 300));
私が思っていることをしないことを提案してください