---
id: video/EurgqGU1jG0
type: video
title: 20260504 - Super fast tests covering 100% of your code
summary: AL test design patterns for fast tests with 100% coverage of the tested objects, shown on a payment provider integration. It uses interfaces, enums, stubs and spies, and passes records as parameters to avoid database calls and external API calls. The presenter reports over 200 tests running in milliseconds.
tier: community
language: en
tags:
  - automated testing
  - code coverage
  - interfaces
  - al development
  - payment integration
  - api integration
  - test patterns
  - environment configuration
  - enums
  - environment abstraction
  - test doubles
  - stubs
system: development
review:
  state: reviewed
  by: opus
  at: "2026-10-07T23:20:46.119Z"
  flags: []
generated:
  at: "2026-10-07T23:20:46.191Z"
  pipeline: 0.2.0
  prompts:
    extract-video: 1
    summarize-video: 2
  input_hash: 82bc241c44a47ed644651f13e10103272852a342bc911d7e2b2219eb461e8c80
evidence:
  - kind: video
    url: https://www.youtube.com/watch?v=EurgqGU1jG0&t=304s
    title: 20260504 - Super fast tests covering 100% of your code
    date: "2026-05-05T09:15:54.000Z"
    commit: null
    t: 304
    quote: and he gave some examples and he he told his audience that he had 100 code coverage
  - kind: video
    url: https://www.youtube.com/watch?v=EurgqGU1jG0&t=410s
    title: 20260504 - Super fast tests covering 100% of your code
    date: "2026-05-05T09:15:54.000Z"
    commit: null
    t: 410
    quote: 100% code coverage is really different from from 99%
  - kind: video
    url: https://www.youtube.com/watch?v=EurgqGU1jG0&t=509s
    title: 20260504 - Super fast tests covering 100% of your code
    date: "2026-05-05T09:15:54.000Z"
    commit: null
    t: 509
    quote: we can only be in production mode when we're running in a production environment. So, basically, if we make a copy of the data
  - kind: video
    url: https://www.youtube.com/watch?v=EurgqGU1jG0&t=709s
    title: 20260504 - Super fast tests covering 100% of your code
    date: "2026-05-05T09:15:54.000Z"
    commit: null
    t: 709
    quote: you can see that they're all running in milliseconds. I can run the tests. I run them all. There's uh a bit over 200
  - kind: video
    url: https://www.youtube.com/watch?v=EurgqGU1jG0&t=747s
    title: 20260504 - Super fast tests covering 100% of your code
    date: "2026-05-05T09:15:54.000Z"
    commit: null
    t: 747
    quote: I have 100% code coverage on everything except for some event subscribers, which which is rather irrelevant, but I every path is covered by
links:
  learn: []
  objects: []
  features: []
  topics: []
  localizations: []
  videos: []
  posts: []
  guidelines: []
video_id: EurgqGU1jG0
channel: yt-areopa
source_name: Areopa webinars
url: https://www.youtube.com/watch?v=EurgqGU1jG0
published_at: "2026-05-05T09:15:54.000Z"
duration_s: 3589
captions: derived
audience:
  - developer
chapters:
  - t: 0
    title: Introduction and housekeeping
  - t: 177
    title: About the presenter and the topic
  - t: 287
    title: Inspiration from Vjeko and coding patterns
  - t: 445
    title: Scenario and requirements for payment integration
  - t: 582
    title: Demo of the payment application
  - t: 709
    title: Test results and code coverage demonstration
  - t: 838
    title: Environment concept and testing scenarios
  - t: 965
    title: Context interfaces and enum-based implementations
  - t: 1109
    title: Environment interfaces and design patterns
  - t: 1243
    title: Reducing paths and code organization strategy
  - t: 1368
    title: Implementation of app environment interface
  - t: 1522
    title: Testing with stub and spy patterns
  - t: 1789
    title: Achieving 100% code coverage with interfaces
  - t: 1896
    title: Testing API calls without external dependencies
  - t: 2060
    title: Simulating API responses with global variables
  - t: 2311
    title: Fast testing through parameter passing and email handling
  - t: 2530
    title: Code hierarchy and minimizing database calls
  - t: 2720
    title: AI development and design considerations
  - t: 2950
    title: Decoupling side effects with event publishers
  - t: 3040
    title: Pure functions and dependency injection design
  - t: 3235
    title: API operation patterns and interface design
  - t: 3423
    title: Addressing limitations and robustness
  - t: 3507
    title: Closing remarks and next steps
features:
  - name: 100% code coverage testing pattern
    status: unclear
    t: 287
    verified: false
    status_source: video
  - name: Payment API integration with environment-aware mode switching
    status: unclear
    t: 433
    verified: false
    status_source: video
  - name: Fast automated testing framework
    status: unclear
    t: 709
    verified: false
    status_source: video
  - name: GitHub AL-Go integration with test reporting
    status: unclear
    t: 780
    verified: false
    status_source: video
  - name: Context interfaces pattern
    status: unclear
    t: 965
    verified: false
    status_source: video
  - name: Environment interfaces
    status: unclear
    t: 1109
    verified: false
    status_source: video
  - name: Enum-based state management
    status: unclear
    t: 1225
    verified: false
    status_source: video
  - name: Test doubles with stubs and spies
    status: unclear
    t: 1575
    verified: false
    status_source: video
  - name: Environment stub implementation for testing
    status: unclear
    t: 1638
    verified: false
    status_source: video
  - name: API testing without external calls
    status: unclear
    t: 1896
    verified: false
    status_source: video
  - name: API spy variables for tracking calls
    status: unclear
    t: 2070
    verified: false
    status_source: video
  - name: Record parameter passing for fast testing
    status: unclear
    t: 2347
    verified: false
    status_source: video
  - name: Application state management for test scenarios
    status: unclear
    t: 2443
    verified: false
    status_source: video
  - name: Single database get optimization
    status: unclear
    t: 2613
    verified: false
    status_source: video
  - name: AI assistance for code generation and testing
    status: unclear
    t: 2740
    verified: false
    status_source: video
  - name: Event publishers for separating concerns
    status: unclear
    t: 2954
    verified: false
    status_source: video
  - name: Pure functions for testability
    status: unclear
    t: 3037
    verified: false
    status_source: video
  - name: Dependency injection parameter hell trade-off
    status: unclear
    t: 3168
    verified: false
    status_source: video
  - name: Modular app architecture
    status: unclear
    t: 3246
    verified: false
    status_source: video
  - name: API operation record pattern
    status: unclear
    t: 3297
    verified: false
    status_source: video
  - name: Interface pattern for consistent signatures
    status: unclear
    t: 3346
    verified: false
    status_source: video
objects_mentioned:
  - other navigate BC
  - interface number series single
  - enum system environment
  - interface I environment
  - codeunit app environment
  - interface API request
  - interface send function
  - codeunit stop production environment code unit
  - interface API interface
  - codeunit payment request task
  - interface environment interface
quotes:
  - t: 304
    text: and he gave some examples and he he told his audience that he had 100 code coverage
    check: fuzzy
  - t: 410
    text: 100% code coverage is really different from from 99%
    check: exact
  - t: 509
    text: we can only be in production mode when we're running in a production environment. So, basically, if we make a copy of the data
    check: exact
  - t: 709
    text: you can see that they're all running in milliseconds. I can run the tests. I run them all. There's uh a bit over 200
    check: exact
  - t: 747
    text: I have 100% code coverage on everything except for some event subscribers, which which is rather irrelevant, but I every path is covered by
    check: exact
---

# 20260504 - Super fast tests covering 100% of your code

> AL test design patterns for fast tests with 100% coverage of the tested objects, shown on a payment provider integration. It uses interfaces, enums, stubs and spies, and passes records as parameters to avoid database calls and external API calls. The presenter reports over 200 tests running in milliseconds.

[Watch on YouTube](https://www.youtube.com/watch?v=EurgqGU1jG0) · Areopa webinars · 2026-05-05 · 59:49 · tier community · reviewed (checked by Opus)

## Overview

The webinar walks through a payment integration app and shows how it reaches 100% code coverage of the objects under test, except event subscribers. The app switches to test mode outside production. The presenter builds this with context interfaces, environment interfaces, and enums in place of booleans, so that each code path can be tested with stub or spy implementations.

It then covers testing API logic without external calls, passing records as parameters so tests use temporary records, and reducing database gets to one. It also covers AI assistance for writing tests, pure functions, event publishers for side effects, the risk of too many parameters, and an API operation record pattern.

## Key points

- Environment interfaces abstract the platform (sandbox or production), current company and evaluation company status, so tests can cover each environment path with stubs.
- A stub returns fixed data without tracking usage; a spy also records which functions were called so tests can check them later.
- API logic is tested by implementing an interface that simulates HTTP responses, so no external calls are made. The real HTTP client implementation is not tested this way.
- Passing records by reference as parameters lets tests use temporary records and skip database inserts and gets. It requires changing function signatures. Passing setup down from the top reduced three gets to one.
- Coverage is 100% only for the objects being tested and excludes event subscribers.
- Moving setup retrieval into parameters is dependency injection and can lead to too many parameters. The presenter suggests rethinking the design or introducing interfaces.
- An API operation record holds the endpoint, method, payload and response so one function can handle any API call. This moves complexity into the record structure.

## Chapters

- [0:00](https://www.youtube.com/watch?v=EurgqGU1jG0&t=0s) Introduction and housekeeping
- [2:57](https://www.youtube.com/watch?v=EurgqGU1jG0&t=177s) About the presenter and the topic
- [4:47](https://www.youtube.com/watch?v=EurgqGU1jG0&t=287s) Inspiration from Vjeko and coding patterns
- [7:25](https://www.youtube.com/watch?v=EurgqGU1jG0&t=445s) Scenario and requirements for payment integration
- [9:42](https://www.youtube.com/watch?v=EurgqGU1jG0&t=582s) Demo of the payment application
- [11:49](https://www.youtube.com/watch?v=EurgqGU1jG0&t=709s) Test results and code coverage demonstration
- [13:58](https://www.youtube.com/watch?v=EurgqGU1jG0&t=838s) Environment concept and testing scenarios
- [16:05](https://www.youtube.com/watch?v=EurgqGU1jG0&t=965s) Context interfaces and enum-based implementations
- [18:29](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1109s) Environment interfaces and design patterns
- [20:43](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1243s) Reducing paths and code organization strategy
- [22:48](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1368s) Implementation of app environment interface
- [25:22](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1522s) Testing with stub and spy patterns
- [29:49](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1789s) Achieving 100% code coverage with interfaces
- [31:36](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1896s) Testing API calls without external dependencies
- [34:20](https://www.youtube.com/watch?v=EurgqGU1jG0&t=2060s) Simulating API responses with global variables
- [38:31](https://www.youtube.com/watch?v=EurgqGU1jG0&t=2311s) Fast testing through parameter passing and email handling
- [42:10](https://www.youtube.com/watch?v=EurgqGU1jG0&t=2530s) Code hierarchy and minimizing database calls
- [45:20](https://www.youtube.com/watch?v=EurgqGU1jG0&t=2720s) AI development and design considerations
- [49:10](https://www.youtube.com/watch?v=EurgqGU1jG0&t=2950s) Decoupling side effects with event publishers
- [50:40](https://www.youtube.com/watch?v=EurgqGU1jG0&t=3040s) Pure functions and dependency injection design
- [53:55](https://www.youtube.com/watch?v=EurgqGU1jG0&t=3235s) API operation patterns and interface design
- [57:03](https://www.youtube.com/watch?v=EurgqGU1jG0&t=3423s) Addressing limitations and robustness
- [58:27](https://www.youtube.com/watch?v=EurgqGU1jG0&t=3507s) Closing remarks and next steps

## Features

| Feature | Status | At |
|---|---|---|
| 100% code coverage testing pattern | status not stated, demoed | [4:47](https://www.youtube.com/watch?v=EurgqGU1jG0&t=287s) |
| Payment API integration with environment-aware mode switching | status not stated, demoed | [7:13](https://www.youtube.com/watch?v=EurgqGU1jG0&t=433s) |
| Fast automated testing framework | status not stated, demoed | [11:49](https://www.youtube.com/watch?v=EurgqGU1jG0&t=709s) |
| GitHub AL-Go integration with test reporting | status not stated, demoed | [13:00](https://www.youtube.com/watch?v=EurgqGU1jG0&t=780s) |
| Context interfaces pattern | status not stated, demoed | [16:05](https://www.youtube.com/watch?v=EurgqGU1jG0&t=965s) |
| Environment interfaces | status not stated, demoed | [18:29](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1109s) |
| Enum-based state management | status not stated, demoed | [20:25](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1225s) |
| Test doubles with stubs and spies | status not stated, demoed | [26:15](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1575s) |
| Environment stub implementation for testing | status not stated, demoed | [27:18](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1638s) |
| API testing without external calls | status not stated, demoed | [31:36](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1896s) |
| API spy variables for tracking calls | status not stated, demoed | [34:30](https://www.youtube.com/watch?v=EurgqGU1jG0&t=2070s) |
| Record parameter passing for fast testing | status not stated, demoed | [39:07](https://www.youtube.com/watch?v=EurgqGU1jG0&t=2347s) |
| Application state management for test scenarios | status not stated, demoed | [40:43](https://www.youtube.com/watch?v=EurgqGU1jG0&t=2443s) |
| Single database get optimization | status not stated, demoed | [43:33](https://www.youtube.com/watch?v=EurgqGU1jG0&t=2613s) |
| AI assistance for code generation and testing | status not stated, demoed | [45:40](https://www.youtube.com/watch?v=EurgqGU1jG0&t=2740s) |
| Event publishers for separating concerns | status not stated, demoed | [49:14](https://www.youtube.com/watch?v=EurgqGU1jG0&t=2954s) |
| Pure functions for testability | status not stated, demoed | [50:37](https://www.youtube.com/watch?v=EurgqGU1jG0&t=3037s) |
| Dependency injection parameter hell trade-off | status not stated | [52:48](https://www.youtube.com/watch?v=EurgqGU1jG0&t=3168s) |
| Modular app architecture | status not stated, demoed | [54:06](https://www.youtube.com/watch?v=EurgqGU1jG0&t=3246s) |
| API operation record pattern | status not stated, demoed | [54:57](https://www.youtube.com/watch?v=EurgqGU1jG0&t=3297s) |
| Interface pattern for consistent signatures | status not stated, demoed | [55:46](https://www.youtube.com/watch?v=EurgqGU1jG0&t=3346s) |

## AL objects mentioned

As heard in the captions. A name that matches one object page by exact type and name links to it; the others stay as named.

- other "navigate BC" at [4:21](https://www.youtube.com/watch?v=EurgqGU1jG0&t=261s)
- interface "number series single" at [16:48](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1008s)
- enum "system environment" at [21:59](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1319s)
- interface "I environment" at [22:35](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1355s)
- codeunit "app environment" at [22:35](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1355s)
- interface "API request" at [18:40](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1120s)
- interface "send function" at [32:11](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1931s)
- codeunit "stop production environment code unit" at [29:17](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1757s)
- interface "API interface" at [31:58](https://www.youtube.com/watch?v=EurgqGU1jG0&t=1918s)
- codeunit "payment request task" at [43:50](https://www.youtube.com/watch?v=EurgqGU1jG0&t=2630s)
- interface "environment interface" at [58:27](https://www.youtube.com/watch?v=EurgqGU1jG0&t=3507s)

Not found in BC28-30: interface "number series single", enum "system environment", interface "I environment", codeunit "app environment", interface "API request", interface "send function", codeunit "stop production environment code unit", interface "API interface", codeunit "payment request task", interface "environment interface".

## Quotes

- [5:04](https://www.youtube.com/watch?v=EurgqGU1jG0&t=304s) "and he gave some examples and he he told his audience that he had 100 code coverage"
- [6:50](https://www.youtube.com/watch?v=EurgqGU1jG0&t=410s) "100% code coverage is really different from from 99%"
- [8:29](https://www.youtube.com/watch?v=EurgqGU1jG0&t=509s) "we can only be in production mode when we're running in a production environment. So, basically, if we make a copy of the data"
- [11:49](https://www.youtube.com/watch?v=EurgqGU1jG0&t=709s) "you can see that they're all running in milliseconds. I can run the tests. I run them all. There's uh a bit over 200"
- [12:27](https://www.youtube.com/watch?v=EurgqGU1jG0&t=747s) "I have 100% code coverage on everything except for some event subscribers, which which is rather irrelevant, but I every path is covered by"

Presenters (as heard): Fred, Finn Pedersen, Vieco, Luke, Hilmar Espen, Hilmar.
