Skill v1.0.1
currentAutomated scan100/100+3 new
name: write-bdd-feature description: Guide for writing BDD (Behaviour-Driven Development) feature files and step definitions for the ODA Canvas test kit. Covers Gherkin conventions, Cucumber.js patterns, step definition templates, utility library usage, and the complete creation workflow. Use this skill when creating new BDD features, writing Gherkin scenarios, or adding step definitions. metadata: version: "1.0.1"
Write BDD Feature — Skill Instructions
Feature File Conventions
File Naming Pattern
UC{use-case-number}-F{feature-number}-{Descriptive-Title}.feature
Examples:
UC002-F001-Install-Component.featureUC003-F004-Expose-APIs-Upgrade-component-with-additional-API.featureUC007-F002-Dependent-APIs-Configure-Dependent-APIs-Single-Downstream.feature
Required Structure
# The 'business stakeholders' for the canvas Behaviour Driven Design are the Engineering teams# from the Vendor of a component, from a Systems Integrator who may be integrating and deploying# a component, or a Service Provider's Operations team who may be supporting a component.@UC{number} # tagged as use case {number}@UC{number}-F{number} # tagged as feature {number} within use case {number}Feature: UC{number}-F{number} {Feature Title}Background: (optional)Given [preconditions that apply to all scenarios]Scenario Outline: {Descriptive scenario name}Given [initial context or precondition]When [action or event occurs]Then [expected outcome]Examples:| Name | PackageName | ReleaseName | ...| Descriptive | example-package | test-release | ...
Standard Header Comment
ALWAYS include this exact comment block at the top of every feature file:
# The 'business stakeholders' for the canvas Behaviour Driven Design are the Engineering teams# from the Vendor of a component, from a Systems Integrator who may be integrating and deploying# a component, or a Service Provider's Operations team who may be supporting a component.
Tagging
Every feature file MUST have two tags on separate lines:
@UC{number}— Use case level tag@UC{number}-F{number}— Feature level tag@SkipTest— Optional, to skip a feature
Parameters
Use single-quoted '{ParamName}' convention in Gherkin step text.
Common Given/When/Then Patterns
Component Installation and Lifecycle
Given an example package '{PackageName}' with '{Count}' ExposedAPI in its '{SegmentName}' segmentGiven a running helm release '{ReleaseName}' from package '{PackageName}'When I install the '{PackageName}' package as release '{ReleaseName}'When I upgrade the '{ReleaseName}' release to package '{PackageName}'When I uninstall the '{ReleaseName}' releaseThen the '{ComponentName}' component has a deployment status of 'Complete'
API Resource Management
Then I should see the '{ExposedAPIName}' ExposedAPI resource on the '{ComponentName}' componentThen I should see the '{DependentAPIName}' DependentAPI resource on the '{ComponentName}' componentThen the '{ExposedAPIName}' ExposedAPI should have a url containing '{UrlPattern}'Then the '{ExposedAPIName}' ExposedAPI should have implementation ready status '{Status}'
Kubernetes Resources
Given a deployment '{DeploymentName}' with '{ReplicaCount}' replicas in namespace '{Namespace}'Then the PDB named '{PDBName}' should exist in namespace '{Namespace}'Then the Service '{ServiceName}' should exist in namespace '{Namespace}'
Identity Management (Keycloak)
Given the Keycloak identity management platform is availableThen the Keycloak realm should contain the client '{ClientName}'Then the client '{ClientName}' should have the role '{RoleName}'
Observability
Then the component '{ComponentName}' should have OpenTelemetry configurationThen a ServiceMonitor resource should exist for '{ComponentName}'
API Gateway Configuration
Then an Apisix Route should be created for the '{ExposedAPIName}' ExposedAPIThen a Kong Route should be created for the '{ExposedAPIName}' ExposedAPI
Segment Types
ODA Components are structured into three segments:
- `coreFunction`: Core business functionality APIs
- `managementFunction`: Administrative and management APIs
- `securityFunction`: Security and access control APIs
Test Data Packages
Available in feature-definition-and-test-kit/testData/:
productcatalog-v1— Basic product catalog componentproductcatalog-v1beta3— Legacy version for seamless upgrade testingproductordercaptureandvalidation-v1— Component with dependent APIs on a product catalog and a product inventoryproductcatalog-dynamic-roles-v1— Component with dynamic role definitionsproductcatalog-enhanced-v1— Component with enhanced API configurations
Default release name: ctk (Canvas Test Kit) Default namespace: components
Step Definition Conventions
Existing Files (DO NOT create duplicates)
ComponentManagementSteps.js— Component installation, upgrade, uninstall, statusAPIManagementSteps.js— ExposedAPI and DependentAPI resourcesAPIGatewayManagementSteps.js— Apisix, Kong route/plugin configurationIdentityManagementSteps.js— Keycloak client, role, permission managementObservabilitySteps.js— ServiceMonitor and OpenTelemetryPDBManagementSteps.js— PodDisruptionBudget managementResourceInventorySteps.js— Generic Kubernetes resource operationsProductCatalogSteps.js— TMF-specific product catalog API interactions
Before Creating New Steps
- Search existing step definition files for similar patterns
- Check if existing steps can be reused or extended
- Only create new steps when no existing pattern matches
Step Definition Template
const resourceInventoryUtils = require('resource-inventory-utils-kubernetes');const packageManagerUtils = require('package-manager-utils-helm');const { Given, When, Then, setDefaultTimeout } = require('@cucumber/cucumber');const assert = require('assert');const NAMESPACE = 'components';const DEFAULT_TIMEOUT = 20 * 1000;const DEBUG_LOGS = false;setDefaultTimeout(DEFAULT_TIMEOUT);/*** [JSDoc comment describing the step's purpose]** @param {string} parameterName - Description of parameter* @returns {Promise<void>}*/Given('step definition pattern {string}', async function (parameterName) {console.log('\n=== Starting [Step Name] ===');try {const result = await resourceInventoryUtils.someOperation(parameterName);assert.ok(result, 'Expected result to be truthy');console.log('✅ Successfully completed [step name]');} catch (error) {console.error(`❌ Error during [step name]: ${error.message}`);throw error;}});
Utility Libraries
Located in feature-definition-and-test-kit/utilities/ (local npm packages linked via file:):
| Package | Purpose | |
|---|---|---|
resource-inventory-utils-kubernetes | K8s resource CRUD, wait for conditions, query status | |
package-manager-utils-helm | Helm install/upgrade/uninstall, chart metadata | |
identity-manager-utils-keycloak | Keycloak authentication, client/role management | |
component-utils | ODA Component API interactions, test data loading | |
observability-utils-kubernetes | ServiceMonitor, Prometheus configuration | |
resource-inventory-utils-TMF639 | TMF639 Resource Inventory API operations |
Creation Workflow
Step 1: Understand Requirements
- Read the use case document in
usecase-library/UC{number}-*.md - Identify the specific behaviour being tested
- Check for similar existing features
Step 2: Create Feature File
- Determine correct UC and F numbers (check existing features for next available)
- Create file at
feature-definition-and-test-kit/features/UC{number}-F{number}-{Title}.feature - Include standard header comment, two-level tags, Feature declaration
- Write Scenario Outline with Examples table (preferred) or individual Scenarios
- Reuse existing Given/When/Then patterns
Step 3: Create Step Definitions (only if needed)
- Add new steps to the appropriate existing file
- Include JSDoc comments
- Use utility libraries — never make direct K8s API calls
- Add error handling and debug logging
Step 4: Update README.md
Add entry to feature-definition-and-test-kit/README.md in the "List of BDD Features" section:
### UC{number} - {Use Case Title}*⏳ [F{number} - {Feature Title}](features/UC{number}-F{number}-{Title}.feature)
Status indicators: ⏳ test defined but not validated, ✅ implemented and passing.
Key Principles
- Reuse over recreation — always search for existing patterns first
- Implementation-agnostic — test Canvas behaviour, not operator internals
- Consistency — follow naming conventions and structure exactly
- Readability — scenarios should be understandable by business stakeholders
- Always update README.md — maintain the feature catalog