| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| Invoke | /bdd:generate |
| Aliases | /bdd, /test:bdd |
| Category | kobic-workflow |
| Complexity | moderate |
| MCP Servers | sequential, context7, serena |
/bdd:generate โ ์๋๋ฆฌ์ค๋ก ํ ์คํธ ์๋ ๋ง๋ค๊ธฐ#
ํ๋ง๋๋ก#
"์ฌ์ฉ์๊ฐ ์ด๋ ๊ฒ ํ๋ฉด ์ด๋ฐ ๊ฒฐ๊ณผ๊ฐ ๋์์ผ ํ๋ค"๋ ์๋๋ฆฌ์ค๋ฅผ ์ฌ๋์ด ์ฝ๋ ๋ฌธ์ฅ์ผ๋ก ์ ์ผ๋ฉด, ๊ทธ๊ฑธ ์ค์ ๋ก ๊ฒ์ฆํ๋ ์๋ ํ ์คํธ ์ฝ๋๋ก ๋ฐ๊ฟ์ฃผ๋ ๋ช ๋ น์ ๋๋ค. ์ํ๋ฌธ์ (์๋๋ฆฌ์ค)์ ์ฑ์ ํ(ํ ์คํธ)๋ฅผ ํ ๋ฒ์ ๋ง๋ค์ด ์ฃผ๋ ๋๊ตฌ๋ผ๊ณ ๋ณด๋ฉด ๋ฉ๋๋ค.
๋๊ฐยท์ธ์ ์ฐ๋์#
- ์๋ก ๋ง๋ ๊ธฐ๋ฅ(Feature)์ด ์๋๋๋ก ๋์ํ๋์ง ์๋์ผ๋ก ๊ฒ์ฆํ๊ณ ์ถ์ ๊ฐ๋ฐ์
- ๋์์ธ ๋ถ์(
/figma:analyze) ๊ณผ์ ์ ๋ง์ง๋ง ๋จ๊ณ์์ ํ ์คํธ๊ฐ ์๋์ผ๋ก ํ์ํ ๋ - ์ด๋ฏธ ์๋ ๊ธฐ๋ฅ์ ๋ค๋ฆ๊ฒ ํ ์คํธ๋ฅผ ๋ถ์ด๊ณ ์ถ์ ๋
๋ฌด์์ ํด์ฃผ๋์#
-
์ฌ๋์ด ์ฝ๋ ์๋๋ฆฌ์ค ๋ฌธ์์ธ
.featureํ์ผ(์:community_list.feature,community_detail.feature,community_form.feature)์ ๋ง๋ค์ด ์ค๋๋ค. ์๋๋ฆฌ์ค ์ ๋ชฉ๊ณผ ์ค๋ช ์ ํ๊ตญ์ด๋ก ์ ์ต๋๋ค. - ๊ทธ ์๋๋ฆฌ์ค๋ฅผ ์ค์ ๋ก ์คํํ๋ ํ ์คํธ ์ฝ๋์ธ Step Definition์ ์๋์ผ๋ก ๋ง๋ค์ด ์ค๋๋ค.
- ์ด๋ฏธ ๋ง๋ค์ด ๋ ๊ณต์ฉ ํ ์คํธ ์กฐ๊ฐ์ด ์์ผ๋ฉด ์๋ก ๋ง๋ค์ง ์๊ณ ์ฌ์ฌ์ฉํด์ ์ค๋ณต์ ์ค์ฌ ์ค๋๋ค.
์ด๋ป๊ฒ ์ฐ๋์#
# ๊ธฐ๋ณธ: community ๊ธฐ๋ฅ์ ์๋๋ฆฌ์ค + ํ
์คํธ ์์ฑ
/bdd:generate community
# ๊ธฐ์กด ๊ธฐํ ๋ฌธ์(.claude/docs)์์ ๊ฐ์ ธ์ ์์ฑํ๊ณ , ์ฝ๋ ์์ฑ๊น์ง ์๋ ์คํ
/bdd:generate community \
--from-claude-docs true \
--run-build true
# ํ
์คํธ ์ฝ๋(Step Definition)๋ง ์์ฑ
/bdd:generate community \
--only-steps true
# ํน์ ํ๋ฉด๋ง ์์ฑ (๋ชฉ๋กยท์์ธ ํ๋ฉด๋ง)
/bdd:generate community \
--screens " list,detail "
feature_name(ํ์): ๋์ ๊ธฐ๋ฅ ์ด๋ฆ. ์)community--screens: ์ด๋ค ํ๋ฉด์ ๋ง๋ค์ง. ์)"list,detail,form"(๋ชฉ๋ก/์์ธ/์ ๋ ฅ)--from-claude-docs: ์ด๋ฏธ ์์ฑ๋ ๊ธฐํ ๋ฌธ์์์ ๋ด์ฉ์ ๊ฐ์ ธ์ต๋๋ค.--only-steps: ํ ์คํธ ์ฝ๋๋ง ๋ง๋ญ๋๋ค.--run-build: ์ฝ๋ ์์ฑ๊น์ง ์๋์ผ๋ก ๋๋ฆฝ๋๋ค.
์์์ ๋ฌด์จ ์ผ์ด ๋ฒ์ด์ง๋์#
- ์ ์๋๋ฆฌ์ค๋ฅผ ์ง๊ธฐ ์ ์ ๋จผ์ ๊ฒ์ โ ์ด๋ฏธ ๋ง๋ค์ด ๋ ๋น์ทํ ํ ์คํธ ์กฐ๊ฐ์ด ์๋์ง ์ฐพ์๋ณด๊ณ , ์์ผ๋ฉด ๊ทธ๋๋ก ์ฌ์ฌ์ฉํฉ๋๋ค(์ค๋ณต ๋ฐฉ์ง).
- ์๋๋ฆฌ์ค ์์ฑ โ "์ฑ ์คํ โ ๋ก๊ทธ์ธ โ ํญ ํด๋ฆญ โ ๊ฒฐ๊ณผ ํ์ธ" ๊ฐ์ ํ๋ฆ์ ์ฌ๋์ด ์ฝ๋ ๋ฌธ์ฅ(ํ๊ตญ์ด ์ ๋ชฉ + ์์ด ๋จ๊ณ)์ผ๋ก ์ ๋ฆฌํฉ๋๋ค.
- ํ ์คํธ ์ฝ๋ ์์ฑ โ ๊ฐ ๋ฌธ์ฅ์ ๋์ํ๋ ์ค์ ๊ฒ์ฆ ์ฝ๋(Step Definition)๋ฅผ ๋ง๋ค๊ณ , ๊ณต์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ ๊ฒ์ ๊ฐ์ ธ๋ค ์๋๋ค.
- ์คํยทํ์ธ โ ํ์ํ๋ฉด ์ฝ๋ ์์ฑ๊ณผ ํ ์คํธ ์คํ๊น์ง ์ด์ด์ ์งํํด, ์๋๋ฆฌ์ค๋๋ก ๋์ํ๋์ง ํ์ธํฉ๋๋ค.
โ๏ธ ์์ธ ์ต์ ยท์คํ ๋ช ์ธ (๊ฐ๋ฐ์ / AI ์์ด์ ํธ์ฉ)
Project Language Rules Summary#
| Category | Language | Note |
|---|---|---|
| Feature title/description | Korean | Write freely |
| Scenario title/description | Korean | Write freely |
| Step pattern | English | Korean Usage comment required at top |
| Step parameter (UI text) | {'Korean value'} | Passed as Dart string |
| Custom Step function | English camelCase | English/Korean annotation in Usage comment |
Triggers#
- When generating BDD tests for a Feature
/figma:analyzePhase 6- When adding BDD tests to existing Features
Context Trigger Pattern#
/bdd:generate {feature_name} [--options]Parameters#
| Parameter | Required | Description | Example |
|---|---|---|---|
feature_name | โ | Feature๋ช (snake_case) | community |
--entity-name | โ | Entity๋ช (Auto-inferred) | Post |
--location | โ | Feature Location | application |
--screens | โ | Screen Type | "list,detail,form" |
--from-claude-docs | โ | Copy from .claude/docs | true |
--only-steps | โ | Generate Step Definitions only | true |
--run-build | โ | Auto Execute build | true |
Project Structure#
feature/{location}/{feature_name}/
โโโ lib/
โ โโโ ...
โ โโโ test_steps/ # ๋๋ฉ์ธ ํนํ ์คํ
๋ผ์ด๋ธ๋ฌ๋ฆฌ
โ โโโ common_steps.dart # Feature ๊ณต์ฉ ์คํ
โ โโโ {feature}_steps.dart # Feature ์ ์ฉ ์คํ
โโโ test/
โ โโโ features/ # .feature ํ์ผ
โ โ โโโ {feature}_list.feature
โ โ โโโ {feature}_detail.feature
โ โ โโโ {feature}_form.feature
โ โโโ steps/ # ์๋ ์์ฑ ์คํ
(build_runner)
โ โโโ ...
โโโ build.yaml
โโโ pubspec.yamlbuild.yaml Configuration#
Recommended structure: Common steps in package/core, each feature imports via externalSteps
targets:
$default:
sources:
include:
- " pubspec.yaml "
- $package$
- lib/$lib$
- lib/**.dart
- test/**
builders:
# BDD Widget Test - Feature ํ์ผ ๊ธฐ๋ฐ ํ
์คํธ ์์ฑ
bdd_widget_test|featureBuilder:
enabled: true
options:
# ์๋ ์์ฑ๋๋ ์คํ
์ ์ฅ ์์น
stepFolderName: test/steps
# ์ธ๋ถ ๊ณต์ฉ ์คํ
๋ผ์ด๋ธ๋ฌ๋ฆฌ
externalSteps:
# Core ๊ณตํต ์คํ
(์ฑ ์ ์ฒด ๊ณต์ฉ)
- package:core/src/test/bdd/common_steps.dart
- package:core/src/test/bdd/navigation_steps.dart
- package:core/src/test/bdd/widget_steps.dart
# Feature ์ ์ฉ ์คํ
(์ ํ์ฌํญ)
# - package:{feature}/test_steps/{feature}_steps.dartStep Definition Writing Rules#
Core Rules#
- Function name: English camelCase (e.g.,
iSeeClassListScreen) - Usage comment: English Step Pattern + Korean purpose description
- Parameters: Korean UI text is passed in
{'Korean Value'}format
Step Definition Template#
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
// =============================================================================
// Given Steps
// =============================================================================
/// Usage: Given the app is running
/// ์ฉ๋: ์ฑ์ ์คํํจ
Future<void> theAppIsRunning(WidgetTester tester) async {
await tester.pumpWidget(const MyApp());
await tester.pumpAndSettle();
}
/// Usage: And user is logged in as {email}
/// ์ฉ๋: {email} ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธ๋ ์ํ๋ฅผ ์ค์
Future<void> userIsLoggedInAs(WidgetTester tester, String email) async {
// ํ
์คํธ์ฉ ๋ก๊ทธ์ธ ์ํ ์ฃผ์
}
// =============================================================================
// When Steps
// =============================================================================
/// Usage: When I tap {text} text
/// ์ฉ๋: {text} ํ
์คํธ๋ฅผ ํญํจ
Future<void> iTapText(WidgetTester tester, String text) async {
await tester.tap(find.text(text));
await tester.pumpAndSettle();
}
/// Usage: And I tap enroll button
/// ์ฉ๋: ๋ฑ๋ก ๋ฒํผ์ ํญํจ
Future<void> iTapEnrollButton(WidgetTester tester) async {
await tester.tap(find.widgetWithText(ElevatedButton, '๋ฑ๋ก'));
await tester.pumpAndSettle();
}
// =============================================================================
// Then Steps
// =============================================================================
/// Usage: Then I see {text} text
/// ์ฉ๋: {text} ํ
์คํธ๊ฐ ํ์๋๋์ง ํ์ธ
Future<void> iSeeText(WidgetTester tester, String text) async {
expect(find.text(text), findsOneWidget);
}
/// Usage: And I see class list screen
/// ์ฉ๋: ์์
๋ชฉ๋ก ํ๋ฉด์ด ํ์๋๋์ง ํ์ธ
Future<void> iSeeClassListScreen(WidgetTester tester) async {
expect(find.byType(ClassListView), findsOneWidget);
}
/// Usage: And I see at least {count} class items
/// ์ฉ๋: ์ต์ {count}๊ฐ์ ์์
ํญ๋ชฉ์ด ํ์๋๋์ง ํ์ธ
Future<void> iSeeAtLeastClassItems(WidgetTester tester, int count) async {
final items = find.byType(ClassListTile);
expect(items, findsAtLeast(count));
}
Feature File Writing Guide#
Core Rules#
- Feature/Scenario title: Korean
- Step Pattern: Write in English (the Pattern the Package matches), and must attach Korean comments.
- Parameters:
{'Korean Value'}Format - Multi-field forms: put field values in a
Givendata table, submit with a single high-levelWhen(domain step) โ do not stack oneWhen/Andper field. See "Examples: Data Table ํผ ์ ์ถ ํจํด" below.
Examples: List Screen#
Feature: ์์
๋ฑ๋ก
ํ์์ด ์ํ๋ ์์
์ ๊ฒ์ํ๊ณ ๋ฑ๋กํ ์ ์๋ ๊ธฐ๋ฅ์ ํ
์คํธํ๋ค.
๋ฑ๋ก ์๋ฃ ํ ๋ง์ดํ์ด์ง์์ ๋ฑ๋ก๋ ์์
์ ํ์ธํ ์ ์์ด์ผ ํ๋ค.
Background:
# ์ฑ ์คํ ๋ฐ ๋ก๊ทธ์ธ ์ํ ์ค์
Given the app is running # ์ฑ์ด ์คํ๋จ
And user is logged in as { ' student@school.com ' } # ์ฃผ์ด์ง ์ด๋ฉ์ผ๋ก ๋ก๊ทธ์ธ ์ํ์
@smoke
Scenario: ์์
๋ชฉ๋ก ์กฐํ
์ฌ์ฉ์๊ฐ ์์
ํญ์ ์ ํํ๋ฉด ํ์ฌ ๋ฑ๋ก ๊ฐ๋ฅํ ์์
๋ชฉ๋ก์ด ํ์๋๋ค.
# ์์
ํญ์ผ๋ก ์ด๋
When I tap { ' ์์
' } text # ' ์์
' ํ
์คํธ๋ฅผ ํญํจ
# ์์
๋ชฉ๋ก ํ๋ฉด ํ์ธ
Then I see class list screen # ์์
๋ชฉ๋ก ํ๋ฉด์ด ํ์๋๋์ง ํ์ธ
And I see at least {3} class items # ์ต์ 3๊ฐ์ ์์
ํญ๋ชฉ์ด ํ์๋๋์ง ํ์ธ
@enrollment @payment
Scenario: ์ ๋ฃ ์์
๋ฑ๋ก
์ฌ์ฉ์๊ฐ ์ ๋ฃ ์์
์ ์ ํํ๊ณ ๊ฒฐ์ ๋ฅผ ์๋ฃํ๋ฉด ๋ฑ๋ก์ด ์๋ฃ๋๋ค.
# ์์
์ ํ
Given I am on class list screen # ์์
๋ชฉ๋ก ํ๋ฉด์ ์์
When I tap { ' ๊ณ ๊ธ ์ํ ' } text # ' ๊ณ ๊ธ ์ํ ' ํ
์คํธ๋ฅผ ํญํจ
# ๋ฑ๋ก ๋ฒํผ ํด๋ฆญ
And I tap enroll button # ๋ฑ๋ก ๋ฒํผ์ ํญํจ
# ๊ฒฐ์ ์งํ
And I complete payment with { ' ์นด๋ ' } # ' ์นด๋ ' ๊ฒฐ์ ์งํ
# ๋ฑ๋ก ์๋ฃ ํ์ธ
Then I see { ' ๋ฑ๋ก์ด ์๋ฃ๋์์ต๋๋ค ' } text # ' ๋ฑ๋ก์ด ์๋ฃ๋์์ต๋๋ค ' ํ
์คํธ๊ฐ ํ์๋จ
And class { ' ๊ณ ๊ธ ์ํ ' } appears in my enrolled list # ๋ด ๋ฑ๋ก ๋ด์ญ์์ ' ๊ณ ๊ธ ์ํ ' ์ด ๋ํ๋จExamples: Form Screen#
Feature: ์์ ์ ์ถ
ํ์์ด ์์ ๋ฅผ ํ์ธํ๊ณ ์ ์ถํ ์ ์๋ ๊ธฐ๋ฅ์ ํ
์คํธํ๋ค.
Background:
Given the app is running # ์ฑ์ด ์คํ๋จ
And user is logged in as { ' student@school.com ' } # ์ฃผ์ด์ง ์ด๋ฉ์ผ๋ก ๋ก๊ทธ์ธ ์ํ์
@homework @submit
Scenario: ์์ ํ์ผ ์ ์ถ
ํ์์ด ์์ ์ ํ์ผ์ ์ฒจ๋ถํ๊ณ ์ ์ถํ๋ฉด ์ ์ถ ์๋ฃ ์ํ๊ฐ ๋๋ค.
Given I am on class list screen # ์์
๋ชฉ๋ก ํ๋ฉด์ ์์
When I tap { ' ์์ ' } text # ' ์์ ' ํ
์คํธ๋ฅผ ํญํจ
And I tap first homework item # ์ฒซ ๋ฒ์งธ ์์ ํญ๋ชฉ์ ํญํจ
And I attach file { ' answer.pdf ' } # ' answer.pdf ' ํ์ผ์ ์ฒจ๋ถํจ
And I tap submit button # ์ ์ถ ๋ฒํผ์ ํญํจ
Then I see { ' ์ ์ถ ์๋ฃ ' } text # ' ์ ์ถ ์๋ฃ ' ํ
์คํธ๊ฐ ํ์๋จ
And homework status is { ' ์ ์ถ๋จ ' } # ์์ ์ํ๊ฐ ' ์ ์ถ๋จ ' ์Examples: Data Table ํผ ์ ์ถ ํจํด#
ํ๋ 3๊ฐ ์ด์์ธ ํผ์ ๊ฐ์ Given ๋ฐ์ดํฐ ํ
์ด๋ธ๋ก ๋๊ณ , When์ ํ๋์ ๋๋ฉ์ธ step์ผ๋ก ์ ์ถํฉ๋๋ค:
Feature: ์ปค๋ฎค๋ํฐ ๊ธ ์์ฑ
ํ์์ด ์ฌ๋ฌ ํญ๋ชฉ์ ์
๋ ฅํด ์ปค๋ฎค๋ํฐ ๊ธ์ ์์ฑํ๊ณ ๋ฑ๋กํ ์ ์๋ ๊ธฐ๋ฅ์ ํ
์คํธํ๋ค.
Background:
Given the app is running # ์ฑ์ด ์คํ๋จ
And user is logged in as { ' student@school.com ' } # ์ฃผ์ด์ง ์ด๋ฉ์ผ๋ก ๋ก๊ทธ์ธ ์ํ์
@community @create
Scenario: ์ฌ๋ฌ ํญ๋ชฉ์ ์
๋ ฅํด ๊ธ ์์ฑ
ํ์์ด ์ ๋ชฉยท๋ด์ฉยท์นดํ
๊ณ ๋ฆฌ๋ฅผ ์
๋ ฅํ๊ณ ๋ฑ๋กํ๋ฉด ๊ธ ์์ฑ์ด ์๋ฃ๋๋ค.
Given user wants to write a post with the following details: # ๋ค์ ์ ๋ณด๋ก ๊ธ์ ์์ฑํ๋ ค ํจ
| ์ ๋ชฉ | ์ค๋์ ํ์ต ํ๊ธฐ |
| ๋ด์ฉ | ์์
์ด ์ ์ตํ์ต๋๋ค |
| ์นดํ
๊ณ ๋ฆฌ | ์์ ๊ฒ์ํ |
When I submit the post # ๊ธ์ ๋ฑ๋กํจ
Then I see { ' ๋ฑ๋ก๋์์ต๋๋ค ' } text # ' ๋ฑ๋ก๋์์ต๋๋ค ' ํ
์คํธ๊ฐ ํ์๋จUsing Predefined Steps#
bdd_widget_test Package default provided steps:
# ์ด๋ฏธ ๊ตฌํ๋์ด ์์ - ์ปค์คํ
์คํ
๋ถํ์
Then I see { ' ํ์ํฉ๋๋ค ' } text # ' ํ์ํฉ๋๋ค ' ํ
์คํธ๊ฐ ํ์๋๋์ง ํ์ธ
And I tap { ' ํ์ธ ' } text # ' ํ์ธ ' ํ
์คํธ๋ฅผ ํญํจ
And I don ' t see { ' ๋ก๋ฉin progress ' } text # ' ๋ก๋ฉin progress ' ํ
์คํธ๊ฐ ํ์๋์ง ์๋์ง ํ์ธ
And I see {Icons.check} icon # ์ฒดํฌ ์์ด์ฝ์ด ํ์๋๋์ง ํ์ธ
And I enter { ' test@email.com ' } into { ' ์ด๋ฉ์ผ ' } input field # ' ์ด๋ฉ์ผ ' ์
๋ ฅ ์นธ์ ' test@email.com ' ์ ์
๋ ฅํจMulti-Package Environment Setup#
To share steps across multiple packages, use bdd_options.yaml:
bdd_options.yaml (Project root)
include: package:core/bdd_options.yaml
externalSteps:
- package:core/src/test/bdd/bdd.dart
- package:{feature}/test_steps/common_steps.darthooks.dart Configuration#
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
// Mock imports
import '../../mocks/mocks.dart';
/// BDD ํ
์คํธ Setup Hook
Future<void> setUp(WidgetTester tester) async {
// Fallback values ๋ฑ๋ก
registerFallbackValues();
}
/// BDD ํ
์คํธ TearDown Hook
Future<void> tearDown(WidgetTester tester) async {
// Pure DI: getIt.reset() ๋ถํ์
}
/// Fallback values ๋ฑ๋ก
void registerFallbackValues() {
// ํ์ํ fallback values ๋ฑ๋ก
// registerFallbackValue(Fake{Entity}());
}
Domain Step Library Advantages#
| Advantage | Description |
|---|---|
| Reusability | Share same steps across multiple feature files |
| Maintenance | Changes to step logic in one place reflect everywhere |
| Consistency | Unified domain terminology and test patterns |
| Multi-package | Can share across packages via externalSteps |
| Auto-complete | IDE provides hints based on Usage comments |
MCP Integration#
| Task | MCP Server | Purpose |
|---|---|---|
| Scenario structuring | Sequential | Systematic scenario design |
| Pattern reference | Context7 | bdd_widget_test Document |
| Code generation | Serena | Step Definition Generation |
Examples#
Basic Usage#
/bdd:generate communityCopy from .claude/docs + Build#
/bdd:generate community \
--from-claude-docs true \
--run-build trueGenerate Step Definitions Only#
/bdd:generate community \
--only-steps trueGenerate Specific Screens Only#
/bdd:generate community \
--screens " list,detail "Test Execution#
# Code generation
dart run build_runner build --delete-conflicting-outputs
# watch mode (recommended during development)
dart run build_runner watch --delete-conflicting-outputs
# Tests ์คํ
flutter test
# Tag filtering
flutter test --tags enrollment
flutter test --exclude-tags payment
# Run specific feature files only
flutter test test/features/class/melos Commands#
# Generate BDD test code
melos run test:bdd --scope={feature_name}
# Run BDD tests
melos run test:bdd --scope={feature_name}
# ์ ์ฒด ์คํ (์์ฑ + ํ
์คํธ)
melos run test:bdd:full --scope={feature_name}Core Rules Summary#
- Step patterns in English: Given/When/Then steps in
.featurefiles must be in English - Function names in English camelCase:
iSeeClassListScreen,iTapEnrollButton - Usage comment required:
/// Usage: And I tap enroll button+/// Purpose: Tap the enroll button - Korean parameters: Pass in
{'Korean value'}format - Reuse shared steps: Utilize
package:core/src/test/bdd/bdd.dart - Utilize externalSteps: Specify external step libraries in build.yaml
- Use tags: Classification tags like
@smoke,@navigation - Step ์ฌ์ฌ์ฉ ์ฐ์ : ์ step ์์ฑ ์ ๋ฐ๋์ ๊ธฐ์กด step ์ธ๋ฒคํ ๋ฆฌ ๊ฒ์ (์๋ ์ฐธ์กฐ)
- Multi-field forms โ Data Table + ๋จ์ผ When: ํ๋ 3๊ฐ ์ด์ ํผ์
Given๋ฐ์ดํฐ ํ ์ด๋ธ๋ก ๊ฐ์ ๋๊ณWhenํ๋(๋๋ฉ์ธ step)๋ก ์ ์ถ โ "Examples: Data Table ํผ ์ ์ถ ํจํด" ์ฐธ์กฐ
Step ์ฌ์ฌ์ฉ ํ์ ์ ์ฐจ (Pre-Generation Check)#
์ .feature ํ์ผ ์์ฑ ์ ๋ฐ๋์ ์คํ:
# ๊ธฐ์กด step ์ธ๋ฒคํ ๋ฆฌ์์ ์ ์ฌ step ๊ฒ์
find . -path " */test/src/bdd/step/*.dart " -exec basename {} \; | sort -u | grep -i " {keyword} "๋ฒ์ฉ Key ๊ธฐ๋ฐ ๊ณต์ Step (/bdd:refactor-steps ์ฐธ์กฐ):
| Step ํจํด | ๊ณต์ step ํจ์ | ๋์ฒด ๋์ |
|---|---|---|
I tap the {'key'} widget | iTapTheWidget | |
I tap the {'text'} text | iTapTheText | ํ ์คํธ ๊ธฐ๋ฐ ํญ |
I enter {'val'} in the {'key'} widget | iEnterInTheWidget | |
the {'key'} widget should be displayed | theWidgetShouldBeDisplayed | |
the {'text'} text should be displayed | theTextShouldBeDisplayed | ํ ์คํธ ๊ฒ์ฆ |
I wait for {'N'} seconds | iWaitForSeconds | ๋๊ธฐ step |
{'key'} = Widget Key ๋ฌธ์์ด (K ํด๋์ค ์์์ ์ผ์น):
๊ฒฐ๊ณผ: ๊ธฐ์กด step๊ณผ ๋งค์นญ๋๋ฉด ์ step ํ์ผ ์์ฑ ์คํต, ๊ธฐ์กด ํ์ผ ์ฌ์ฌ์ฉ.
Reference Agents#
- Detailed implementation rules:
${CLAUDE_PLUGIN_ROOT}/commands/agents/bdd-scenario-agent.md - Step ์ฌ์ฌ์ฉ ๋ถ์:
${CLAUDE_PLUGIN_ROOT}/agents/bdd-step-reuse-agent.md - Step ๋ฆฌํฉํ ๋ง:
/bdd:refactor-steps