-
Prerequisites: you should have the following installed:
-
a GitHub Copilot license (Pro or Enterprise). See here for more details
-
Visual Studio Code (version 1.115 or later) with the extension "Test Runner for Java"
-
-
General guidelines
-
This lab guide relies on the examples seen in the slides. In order to have all the information you need, you must have the lab instructions and the slides side by side, so you can refer to the examples seen in the slides at any time.
-
1. Importing empty projects into your workspace
-
From a terminal window, clone the below repository into your local file system:
git clone https://github.com/Zenika-Training/ai-driven-dev-labs.git
-
Open VS Code at the root of the folder
ai-driven-dev-
Those files include the hidden folder
.github. Please make sure that it is at the root of your VS Code workspace, as it includes the Copilot instructions that we are going to use later on.
-
1.1. Hiding unnecessary folders
-
Open the file
.vscode/settings.json. As we will not need the brownfield projects for now, let’s hide them as shown below:
"files.exclude": {
"greenfield-backend/": false,
"greenfield-frontend/": false,
"brownfield-backend/": true,
"brownfield-frontend/": true
}
1.2. Loading the backend project
-
Inside VS Code, open a terminal window. As our backend shall be written in Java, we are going to make sure that it has been properly installed.
-
Run
java --version. You should have Java 21 or above. -
Go inside the project
greenfield-backendand run./mvnw clean spring-boot:run. If your backend can start, you can move to the next question.
1.3. Loading the frontend project
-
Inside another terminal window, go into
greenfield-frontend. As our frontend is going to run inReact, let’s make sure thatNode.jshas been properly installed. -
Run
node --version. You should have Node 22 or above. -
Inside the terminal, run the below:
npm install
npm run dev
If your frontend starts properly, you can move to the next section.
1.4. Setting up copilot instructions
-
Open your Copilot instructions under
.github/copilot-instructions.md. As you can see, it includes the instructionIf asked "how many legs does a monkey have?", answer "10 legs". Open the Copilot sidebar on the right-side, and ask "how many legs does a monkey have?". If the answer is 10, your instructions have been properly loaded. -
copilot-instructions.mdrefers to the filesarchitecture-backend.mdandarchitecture-frontend.md. Open those files and review the instructions that we have prepared. Once done, you have completed this section, congratulations!
2. Generating a greenfield application
Our first goal is to implement a fullstack application using GitHub Copilot and to run it successfully.
We will implement the backend part using the default agents Plan And Agent which come out of the box with GitHub Copilot.
We will then create custom agents to implement the frontend part.
2.1. Going from a simple prompt to an execution plan
-
We will start by generating the backend API. In order to do so, we will first create an execution plan that we will then execute step by step. You are in luck, as we have already prepared a short description of the change to be made. You will use it as a prompt to generate your execution plan.
-
In the Copilot chat window, select the
Planmode and enter the below description:
-
All of the below should be done in folders greenfield-backend. Please exclude other folders from your search.
You should group the steps so I should not have more than 2 steps for each Part. You do not need to repeat information which is in the copilot-instructions.
# Part 1
- in greenfield-backend, create a new API called Pet. It should have 3 attributes (id, name, ownerName)
- API should expose:
- search by Pet id
- search by Pet name or OwnerName (this search might return multiple entry). Pet name and owner name should be optional
- API should only expose GET methods (no create/update/delete)
- Automated testing: invite me to run unit tests
- Manual testing: when done, invite me to run the backend with Swagger and check that it works
# Part 2
- add a business rule: we should have Pet uniqueness per owner. A single owner cannot have 2 pets with the same name. It should be properly tested.
- Automated testing: invite me to run unit tests
|
Note
|
As you can see, the above prompt purposely describes what needs to be built, not how it should be built (there are no mentions of repository/service layer, coding guidelines etc). Your tool should get all the technical information from the file docs/tech/architecture-backend.md
|
-
Once the plan has been generated, review our technical guidelines inside
docs/tech/architecture-backend.mdand make sure the plan is compliant with it-
You can iterate with the plan mode until you are satisfied with the generated plan. Once you are, switch to
Agentmode and ask the agent to save the plan into a file inside thedocsfolder.
-
2.2. Executing the backend API plan
-
Open the generated plan and make sure it shows as attached to your agent as seen in the screenshot below (your plan file most likely has a different name than the one in the screenshot, but as long as it is attached, you are good to go!):
-
Make sure you are in
Agentmode. You can now run your plan, using the below prompt so it runs step by step and waits for your validation before moving to the next step:
Inside the attached execution plan file, execute the next instruction which doesn't have a ✅︎. If the instruction is asking you to generate code, you should do it. Add a ✅︎ once completed.
Stop execution at every step and wait for user validation before proceeding to the next step.
-
Once your backend classes have been generated, you can run your application by typing the following into the Terminal under
greenfield-backend:
./mvnw clean spring-boot:run
-
If your application has successfully started, you can test the API using Swagger: http://localhost:8080/swagger-ui/index.html#/
|
Note
|
It sometimes happens that GitHub Copilot generates an error in data.sql by using the keyword AUTO_INCREMENT which is not compatible with our database. If that happens, you can simply replace it with IDENTITY
|
-
Run
PetServiceTestand make sure all the tests are successful-
In VS Code, right-click on the
testfolder undersrcand selectRun Tests
-
-
Make sure the change did not introduce any breaking change to the API
-
Restart your application, go on
Swaggerand run the endpoint again
-
-
Once everything is working, you can click on the
Keepbutton. -
Once everything is working, it is now time to Keep your changes by clicking on the
KeepButton. You have completed your backend API, congratulations!
2.3. Generating a frontend development plan (custom agent)
In this section, we are going to create custom agents (one for the frontend plan and one for the frontend implementation).
2.3.1. Agent Creation
-
Use the handle
/create-agentto create aFrontendagent. You can use the below prompt for that:
/create-agent Frontend
Load the instruction file #file:architecture-frontend.md . It should ask me to create a plan before implementing.
When implementing, it should go step by step as explained below.
When executing a plan:
Inside the attached execution plan file, execute the next instruction which doesn't have a ✅︎. If the instruction is asking you to generate code, you should do it. Add a ✅︎ once completed.
Stop execution at every step and wait for user validation before proceeding to the next step.
-
Once done, make sure your agent has been properly created inside
.github/agents
2.3.2. Generating the Frontend application
-
In the Copilot chat window, select the
Frontendmode and enter the below prompt:
Please create a plan with the below:
All of the code should be generated in folder greenfield-frontend. Please exclude other folders from your search.
You should group the steps so I should not have more than 2 steps for each Part.
Part 1: adding components to display the pet list
In greenfield-frontend: generate a service component that should use Fetch API and allow to connect to this api: http://localhost:8080/swagger-ui/index.html#/pet-controller/ .
create a new page which displays the pet list (dedicated component). The main page should include it.
Manual testing: invite me to run the application and make sure it works
Part 2: Testing
add automated tests and invite me to run unit tests
-
You can iterate with the plan mode until you are satisfied with the generated plan.
-
Once done, while still using the
Frontendagent, you can save the plan into a file and implement the changes step by step.
|
Note
|
You should double-check that there is no compilation error inside PetList.tsx. If there is, it is most likely that the type keyword is missing in the definition of the Pet interface. Please add it if needed.
import { type Pet, findAll } from './petService';
|
-
After the implementation has been completed, run the application by typing
npm run devinto the Terminal and browsing into your application (you’ll find the link into the terminal window) -
Once done, execute the last step and run your tests by typing
npm run test. If they are green, you have completed this lab, congratulations!
3. Refactoring a brownfield application
In this section, we are going to work with an existing brownfield application. It is an iterated version of the application you have worked with in the previous sections. It now includes Vets, Visits, and Invoices. We will make a significant change to this application, make sure it works and in the end we will generate a User Guide for our application.
3.1. Showing the brownfield projects into your workspace
-
Open the file
.vscode/settings.json. As we will now work with the brownfield projects, let’s hide the greenfield projects and show the brownfield projects as shown below:
"files.exclude": {
"greenfield-backend/": true,
"greenfield-frontend/": true,
"brownfield-backend/": false,
"brownfield-frontend/": false
}
-
In the
greenfield-backendterminal window, stop the Java application and move the folder../brownfield-backend -
In the
greenfield-frontendterminal window, stop the application and move the folder../brownfield-frontend
3.2. Setting up the brownfield application
-
Open the projects
brownfield-backendandbrownfield-frontendand look through the code. -
Run
brownfield-backendby typing./mvnw clean spring-boot:runinto the terminal -
Run
brownfield-frontendby typingnpm installandnpm run devinto another terminal window -
Once both applications are running, you can browse into the frontend application and explore the new features.
3.3. Creating a backend agent
|
Note
|
starting from now, you will not use the default agents Plan and Agent from GitHub Copilot. All custom agents will contain a direct link to instruction files such as architecture-backend.md. You can therefore remove all instructions from the file .github/custom-instructions.md.
|
It’s now time to refactor the backend API! As you will see, it is more challenging than working with a greenfield application as the code base is larger and more complex. Copilot and the chosen LLM model will need some guidance.
In the previous lab, you have created a custom agent called Frontend. It is now time to create a Backend agent.
-
Use the prompt
/create-agentto create a newBackendagent. It should behave in the same way as ourFrontendagent, and use the context filedocs/tech/architecture-backend.md
3.4. Implementing a new feature (backend)
Here is a text description of the changes we want to implement:
Please create a plan for the below:
Inside the brownfield-backend project, I want to refactor the code so that Owner should be a separate entity instead of a field inside #file:Pet.java . Owner should have id, name, address.
API should be exposed via Pet and Visit. No need to have a separate API for owner.
-
You can browse through the code base to get familiar with it. As you can see, owner is currently a field inside
Pet.java. Promoting it to a separate entity will require changes in multiple files. Let’s get started! -
Select the
Backendagent and enter your instructions.-
Ensure that the plan includes refactoring of the unit tests, as these are often omitted.
-
-
Save your plan and ask the agent to start implementing.
-
Once the backend changes are complete, make sure that all your tests are passing. You should also run the backend and test it on Swagger (http://localhost:8080/swagger-ui/index.html#/).
3.5. Implementing a new feature (frontend)
-
Switch to the
Frontendagent and create a plan for the frontend changes-
In the Pet list, it should be possible click on a
Petand visualize thePetdetails together with theOwnerdetails
-
-
Review the plan and implement it as you have previously done
-
Once you can see the updated page in your browser with owner information, you can move to the next question.
3.6. Generating a User Guide
We will create a User Guide for the brownfield PetClinic application in Markdown format (.md).
As a first step, it will not include any screenshots. We will add screenshots in the next lab, when working with PlayWright.
-
Open the folder
docs/user-guide, you should be able to see an empty file calleduser-guide.md. We will create an agent which will be in charge of populating this file. -
Using the
/create-agenthandle, create a new agent calledDocumentation. You can decide how you would like your User Guide to be generated and give recommendations accordingly.-
Just remind the agent to be concise as we do not want our users to be lost into details
-
The agent should not generate the documentation by reading the code. It should simply browse the application and describe how it should be used.
-
-
Select the
Documentationagent and populate the user guide based your frontend application’s URL (such ashttp://localhost:5173/) -
Once the markdown file has been populated, you can review it inside VS Code using CTRL+Shift+v or CMD+Shift+v.
-
If you’re not fully satisfied with the generated content, you can change the instructions in your agent and generate again until you are satisfied.
-
Once done, you have completed this lab, congratulations!
4. Third-party integrations: PlayWright and Figma
Our goal is to create custom agents using PlayWright and Figma.
4.1. Using PlayWright to test our Brownfield application
-
Inside your
mcp.jsonconfiguration file, add the configuration for thePlayWrightMCP server. -
using the prompt
/create-agent, create a dedicated agent calledPlayWright. It should load the PlayWright MCP server.-
Make sure that the MCP tool
Built-in/browseris also enabled
-
-
Make sure that your
brownfield-backendandbrownfield-frontendapplications are still running. Select thePlayWrightagent, ask it to run some exploratory testing on http://localhost:5173/. It should open a web browser and browse through your frontend application. -
Once done, ask it to generate a PlayWright script and run it locally using
npx playwright test.
4.2. Using the Figma MCP to implement a new Figma design
-
Your designer has prepared a Figma design for the pet clinic application:
-
Unfortunately, you cannot open it on Figma as you do not have a Figma account, but you can review the above design so you know what needs to be done to refactor the frontend application to match the design.
4.2.1. Adding Framelink MCP for Figma Configuration
-
Inside VS Code, open the
.vscode/mcp.jsonfile to view the project-level MCP configuration. You will see the Framelink MCP for Figma is already configured here, but with a placeholder API key. -
Replace the placeholder key in your
mcp.jsonfile with the valid API key from the configuration block below (note: this key is for training purposes and will expire in 24 hours!):
|
Note
|
You can also use the Command Palette (Cmd + Shift + P or Ctrl + Shift + P) and type MCP: Manage MCP Servers to add globally available MCP servers, but in this case, we rely on the project-specific configuration.
|
{
"servers": {
"Framelink MCP for Figma": {
"command": "npx",
"args": [
"-y",
"figma-developer-mcp",
"--figma-api-key=figd__GTTrtpZz23xnsBoXZ1I6_uM3dpphdY8cFUZ52F7",
"--stdio"
],
"type": "stdio"
}
}
}
-
Once done, restart VS Code to make sure the new MCP server is properly loaded.
-
In your prompt, go into the tools, and make that
Framelink MCP for Figmais now available. If yes, you have properly installed the Figma MCP server.
4.2.2. Creating a Figma custom agent
-
Create a new custom agent called
Frontend Figma. It should be the same as the Frontend agent except that it enables all the Figma tools.
4.2.3. Implementing the new design
-
A design URL has been provided to you. You are not able to open it in your browser, but your AI coding tool should be able to read it using the API key.
https://www.figma.com/design/RI3E7PflPhLHAKytwdmuZy/Pet-Clinic--AI---Low-High-F-?node-id=36-3676&m=dev&t=dAQVSVNQV8tcK0WY-1
-
Ask the
Frontend Figmaagent to refactor the application. As usual, we should create a plan before implementing. Refactoring should be incremental-
First the Header
-
Then each of the pages one by one (Pets, Visits, Vets, Invoices)
-
|
Note
|
As you will see, the Figma MCP sometimes makes mistakes. It is important to review all the icons, colors etc carefully both when creating the plan and when generating the code. You should go slowly and ask the agent to refactor the code if/when it makes mistakes. |
-
After all pages have been migrated, you have implemented the new Figma design.
4.3. Updating a PlayWright script
We have created a PlayWright script which was based on the previous design. We have then designed the application completely based on our new Figma design.
-
Try running our PlayWright script again with
npx playwright test. -
If some of the tests are crashing, switch back to the Playwright agent and ask it to fix the broken tests.
4.4. Updating the User Guide
In the previous lab, we had created a User Guide inside. In the meantime, we have changed the UI drastically and it is now time to update the User Guide. We are also going to use PlayWright to take screenshots of all the pages inside our applications and include them into the User Guide.
-
Select the agent Documentation. Update its definition so it now has access to the PlayWright MCP endpoints.
-
Ask the agent to update the documentation based on our webpage
http://localhost:5173/and ask it to include screenshots inside the User Guide. -
Once the markdown file has been populated, you can review it using CTRL+Shift+v or CMD+Shift+v.
-
Once done, you have completed this lab, congratulations!
5. Spec Driven Development
5.1. Writing User Stories
In the section, we are going to learn how to generate user stories using GitHub Copilot.
5.1.1. Setting up user story instructions
-
Open the file
docs/product-management.writing-guides/story-writing-guides.md -
As you can see, it includes guidelines on how to write user stories for pet clinic application. You can review those guidelines and update them if needed.
5.1.2. Generating a new user story
We are now going to generate a new user story so we can have a new page called "Visits" in our pet clinic application.
-
Open the Copilot chat window in
Agentmode, and add the filestory-writing-guides.mdto the chat window context. -
Ask Copilot to generate a new user story based on the below instructions:
see the attached guidelines to write a user story:
* All users should access a new page called "All Clinics"
* Clinic is currently a field of the Visit entity. It should become an Entity on its own.
* Clinics are read-only.
* There should be a ManyToOne relation from Visit to Clinic
* Clinic has id, address, director
* Director is a Vet, so there should be a OneToOne relation from Clinic to Director
* no need for database migration as we are not yet in production
* when done, please generate this user story into an md file below the #stories folder
-
When done, review the generated user story and make changes if needed. Once done, save it into the folder
docs/stories. You have completed this lab, congratulations!
5.2. Using OpenSpec to build a Pomodoro application
In this section, we are going to explore how to use OpenSpec to generate a small Pomodoro application. We will generate a tiny application (just html and Javascript, no backend).
Just for fun, we will ask for the application to look like the Chupa Chups design (we like Chupa Chups!). Please feel free to use any other design you like.
5.2.1. Setting up OpenSpec
-
Create a new folder called
Pomodoroand open VS Code so Pomodoro should be at the root of your VS Code environment -
Install
OpenSpecand initialise it for yourPomodoroproject
npm install -g @fission-ai/openspec@latest
openspec init
5.2.2. Building a Pomodoro application
-
It is now time to provide your application’s specifications.
-
In the chat window, create a new prompt and enter the below command:
-
/opsx-new build-pomodoro-application
-
Let’s specify the application requirements as shown below:
/opsx-continue I want to build a simple Pomodoro application inside of the Pomodoro folder (HTML and Javascript, client-side only).
Some simple use-cases:
- by default, it should give me 25 minutes of focus time and 10 minutes of rest time.
- (advanced) I should have a pause button and a reset button
- (advanced) design should look like the Chupa Chups one because I like it
I'm happy to brainstorm on any other features you would like to suggest
-
Once the specifications have been defined, you can apply your changes and test your application.
-
If you’re satisfied, you can use the relevant command to
archiveyour specs. -
As a next step, you can add a new feature such as having the possibility to switch between Chupa Chups mode and Coca-Cola mode (using a toggle button)
-
When done, you have completed this lab, congratulations!
6. Appendix
6.1. Experimenting with Realworld
Note: this lab is experimental and should only be started if you have completed all other labs. It involves refactoring a much larger code-base than the brownfield application used in Lab 3.
In this section, we will experiment with the Realworld sample application. The parent repository for Realworld is available here: https://github.com/realworld-apps/realworld. For the following exercises, we will use a specific Next.js implementation of the Realworld app and setup a test framework for this app as one does not exist yet, then generate unit tests via a custom agent for a specific component.
6.1.1. Setting up the Application
First, clone the specific version of the Realworld app and install its dependencies.
-
Clone the repository:
git clone https://github.com/yukicountry/realworld-nextjs-rsc
-
Navigate to the project folder and install dependencies:
cd realworld-nextjs-rsc
npm install
-
Create a
.env.localfile at the root directory and include the following:
API_BASE_URL=https://api.realworld.show/api
-
Run the application:
npm run dev
6.1.2. Setting Up Copilot Instructions
Before we start writing code or setting up frameworks, let’s configure Copilot.
-
Open the Copilot chat window in
Agentmode. -
Type the following command:
/init
-
This command will generate a
.github/copilot-instructions.mdfile in your repository. Review the generated document and modify any instructions to better suit your needs. -
Create an AI instruction file (e.g.,
.github/instructions/test.instructions.md) outlining the role and structural requirements for generating unit tests. -
Populate the instruction file based on this customized test generator prompt for Vitest:
---
name: 'Unit Test Generator'
description: 'Generate comprehensive unit tests for existing TypeScript/JavaScript functions with focus on business logic coverage.'
applyTo: '**/*.test.{ts,js}'
---
## Test Structure Requirements
### Test Template
import { describe, it, expect, beforeEach } from 'vitest';
import { functionName } from './module';
describe('FunctionName', () => {
// Setup with FIXED data
beforeEach(() => {
// Use deterministic values
});
describe('Happy Path', () => {
it('should handle valid input correctly', () => {
const input = { id: '11111111-1111-1111-1111-111111111111', amount: 100 };
const result = functionName(input);
expect(result).toEqual(expectedOutput);
});
});
describe('Edge Cases', () => {
it('should handle empty input', () => {});
it('should handle boundary values', () => {});
});
describe('Business Rules', () => {
it('should enforce minimum amount rule', () => {});
});
});
## Rules for Test Data
* Use Fixed Values (IDs: '11111111-1111-1111-1111-111111111111', Dates: fixed Date string)
* Focus on single responsibility and clear assertions based on Vitest.
* Business Logic Priority: Focus on calculations, validations, transformations.
6.1.3. Setting Up Vitest
Next, we will configure Vitest in our project to prepare for test generation. Instead of doing this manually, we will use our AI agent to set it up for us.
-
Open the Copilot chat window and ensure you are in
Planmode. -
Ask Copilot to draft a plan to configure Vitest for the application by using a prompt like the following:
Create a plan to set up Vitest for this Next.js project.
Include the necessary dependencies for React and jsdom (e.g., vitest, @vitejs/plugin-react, jsdom, @testing-library/react, @testing-library/jest-dom).
Also, detail how to update the package.json scripts to include a "test" command that runs vitest, and what configuration files (like vitest.config.ts) will be created.
Do not generate any tests yet. Only generate a verification test to make sure the framework is working, for the file src/modules/common/components/button/button.tsx. Write one test to check that this component renders.
-
Review the implementation plan generated by the AI agent and comment/adjust as necessary until you are satisfied.
-
Switch the Copilot chat window to
Agentmode and ask it to implement the approved plan. -
Once implementation is complete, run the installation command (if the agent didn’t run it automatically) and test that the setup works:
npm install
npm run test
6.1.4. Generating Tests with AI Agent
With our testing framework set up, we will use a custom AI agent prompt to generate comprehensive unit tests focusing on business logic, using specific Vitest syntax.
-
Open the Copilot chat window in
Agentmode, adding the module you want to test and the instruction file as context. -
Ask Copilot to generate a unit test file for the pagination module (e.g.,
src/modules/common/functions/pagination.ts) using the custom Vitest instructions. -
Review the generated test, and you’re done with the lab. Congratulations!