test(client): 新增设备侧集成测试(真机跑通后端可达性)
红线第 10 条(设备验证必须设备侧取证)配套:integration_test/app_backend_test.dart
在手机进程里真实请求 /app/home/feed 与 /app/dramas/{id},并用真 App 断言首页剧目列表能渲染。
把 API_BASE_URL 打进设备日志,便于区分地址不对与设备连不上。
注意:真机执行由用户负责(用户 20:45 指令),本文件按原样交付、不再改动。
本项目 iOS 用 SPM,无 Podfile,不需要 pod install。
This commit is contained in:
1 parent
d7eff4ca59
commit
84a1f58a0a
3 files changed
+118
No files matched your search
@@ -0,0 +1,74 @@
|
|||||||
|
// Author: fruit.com.cn
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:fruitshorts/app.dart';
|
||||||
|
import 'package:fruitshorts/core/config/app_config.dart';
|
||||||
|
import 'package:fruitshorts/core/data/remote/api_client.dart';
|
||||||
|
import 'package:fruitshorts/core/data/remote/catalog_api.dart';
|
||||||
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
|
||||||
|
/// 设备侧集成测试:**在手机进程里**真实请求开发机上的 app-api。
|
||||||
|
///
|
||||||
|
/// 跑法(红线第 10 条要求的"设备侧取证"):
|
||||||
|
/// ```
|
||||||
|
/// IP=$(ipconfig getifaddr en0)
|
||||||
|
/// flutter test integration_test -d <device-id> --dart-define=API_BASE_URL=http://$IP:8081
|
||||||
|
/// ```
|
||||||
|
/// 断言失败时会把实际使用的地址一起打出来,便于区分"地址不对"还是"设备连不上"。
|
||||||
|
void main() {
|
||||||
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
final baseUrl = AppConfig.apiBaseUrl;
|
||||||
|
|
||||||
|
testWidgets('should_fetch_home_feed_and_drama_detail_when_device_reaches_backend', (
|
||||||
|
tester,
|
||||||
|
) async {
|
||||||
|
debugPrint('[device] API_BASE_URL=$baseUrl');
|
||||||
|
final client = ApiClient(baseUrl: baseUrl);
|
||||||
|
addTearDown(client.close);
|
||||||
|
final api = CatalogApi(client);
|
||||||
|
|
||||||
|
final feed = await api.homeFeed();
|
||||||
|
expect(
|
||||||
|
feed.dramas,
|
||||||
|
isNotEmpty,
|
||||||
|
reason: '设备侧拿不到首页列表(API_BASE_URL=$baseUrl)',
|
||||||
|
);
|
||||||
|
debugPrint('[device] 首页分区=${feed.sections.length} 剧目=${feed.dramas.length}');
|
||||||
|
|
||||||
|
final card = feed.dramas.first;
|
||||||
|
expect(card.id, isNotEmpty, reason: '设备侧首页卡片 id 为空');
|
||||||
|
|
||||||
|
final detail = await api.dramaDetail(card.id);
|
||||||
|
expect(detail.id, card.id, reason: '详情返回的 id 与卡片不一致');
|
||||||
|
expect(
|
||||||
|
detail.episodes,
|
||||||
|
isNotEmpty,
|
||||||
|
reason: '设备侧拿到的详情没有剧集(dramaId=${card.id})',
|
||||||
|
);
|
||||||
|
debugPrint('[device] 详情 id=${detail.id} 剧集=${detail.episodes.length}');
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('should_render_home_drama_list_when_app_boots_on_device', (
|
||||||
|
tester,
|
||||||
|
) async {
|
||||||
|
// 用真 App(真网络、真目录控制器):首页底部标签栏出现即代表"剧目列表加载成功",
|
||||||
|
// 也就是用户在真机上遇到的那个「剧目列表加载失败」已经消失。
|
||||||
|
await tester.pumpWidget(const LumaDramaApp());
|
||||||
|
|
||||||
|
var loaded = false;
|
||||||
|
for (var attempt = 0; attempt < 60 && !loaded; attempt++) {
|
||||||
|
await tester.pump(const Duration(milliseconds: 500));
|
||||||
|
loaded = find.byKey(const Key('home-tabs-bar')).evaluate().isNotEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(
|
||||||
|
loaded,
|
||||||
|
isTrue,
|
||||||
|
reason: '首页 30 秒内没渲染出剧目列表(API_BASE_URL=$baseUrl)',
|
||||||
|
);
|
||||||
|
debugPrint('[device] 首页剧目列表已渲染:API_BASE_URL=$baseUrl');
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -134,6 +134,11 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_driver:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
flutter_launcher_icons:
|
flutter_launcher_icons:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@@ -165,6 +170,11 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
fuchsia_remote_debug_protocol:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
html:
|
html:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -189,6 +199,11 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.12.0"
|
version: "4.12.0"
|
||||||
|
integration_test:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
intl:
|
intl:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -333,6 +348,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.5.2"
|
version: "6.5.2"
|
||||||
|
process:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: process
|
||||||
|
sha256: "4242ba3508d37e01808bdf71ad1d5bb93a8d671bf2e7450e6b1b353fb0808891"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.6"
|
||||||
provider:
|
provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -434,6 +457,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.1"
|
version: "1.4.1"
|
||||||
|
sync_http:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sync_http
|
||||||
|
sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.1"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -522,6 +553,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
|
webdriver:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: webdriver
|
||||||
|
sha256: "28b82ec894fed45dd71c23ba62d1af973ed97dd59a4f5790a4d38b0b13e5657e"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.2.0"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -46,6 +46,11 @@ dev_dependencies:
|
|||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
|
# 设备侧集成测试:真机/模拟器进程里真实发请求,验证"设备能不能连到开发机后端"
|
||||||
|
# (红线第 10 条:设备验证必须设备侧取证,不能用开发机 curl 充数)
|
||||||
|
integration_test:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
# The "flutter_lints" package below contains a set of recommended lints to
|
# The "flutter_lints" package below contains a set of recommended lints to
|
||||||
# encourage good coding practices. The lint set provided by the package is
|
# encourage good coding practices. The lint set provided by the package is
|
||||||
# activated in the `analysis_options.yaml` file located at the root of your
|
# activated in the `analysis_options.yaml` file located at the root of your
|
||||||
|
|||||||
Reference in new issue
Block a user