====== Testing ======
Strategija testiranja i framework za WvdS FPC RAD Studio.
===== Vrste testova =====
^ Vrsta ^ Opseg ^ Alati ^ Izvršavanje ^
| Unit-Testovi | Pojedinačne funkcije | FPCUnit | Lokalno |
| Integration-Testovi | Interakcija komponenti | FPCUnit | Lokalno |
| E2E-Testovi | Cijeli Extension | VS Code Test Runner | CI |
===== Unit-Testovi =====
==== Struktura ====
sources/
├── extensions/
│ └── wvds.vscode.build/
│ ├── pas/
│ │ ├── Build.Service.pas
│ │ └── Build.Models.pas
│ └── tests/
│ ├── Build.Service.Tests.pas
│ └── Build.Models.Tests.pas
==== Test-Framework ====
unit Build.Service.Tests;
{$mode objfpc}{$H+}
interface
uses
TestFramework,
Build.Service,
Build.Models;
type
TBuildServiceTest = class(TTestCase)
published
procedure TestValidatePath_ValidPath_ReturnsTrue;
procedure TestValidatePath_InvalidPath_ReturnsFalse;
procedure TestGenerateCommand_DebugMode_IncludesDebugFlags;
end;
implementation
procedure TBuildServiceTest.TestValidatePath_ValidPath_ReturnsTrue;
var
Error: string;
begin
CheckTrue(ValidateBuildPath('%USERPROFILE%\Projects\MyApp', Error));
CheckEquals('', Error);
end;
procedure TBuildServiceTest.TestValidatePath_InvalidPath_ReturnsFalse;
var
Error: string;
begin
CheckFalse(ValidateBuildPath('', Error));
CheckNotEquals('', Error);
end;
procedure TBuildServiceTest.TestGenerateCommand_DebugMode_IncludesDebugFlags;
var
Config: TWvdSBuildConfig;
Command: string;
begin
Config.Mode := bmDebug;
Config.ProjectPath := 'test.lpr';
Command := GenerateBuildCommand(Config);
CheckTrue(Pos('-g', Command) > 0, 'Debug flag missing');
CheckTrue(Pos('-O0', Command) > 0, 'No-optimization flag missing');
end;
initialization
RegisterTest(TBuildServiceTest.Suite);
end.
==== Naming Conventions ====
Test{Feature}_{Scenario}_{ExpectedResult}
Primjeri:
TestValidatePath_ValidPath_ReturnsTrue
TestValidatePath_EmptyString_ReturnsFalse
TestGenerateCommand_ReleaseMode_IncludesOptimization
===== Osiguravanje testabilnosti =====
==== Dizajn Servisa ====
// TESTABILNO - Bez UI-ovisnosti
function ValidateName(const AName: string; out AError: string): Boolean;
// NIJE TESTABILNO - UI u logici
procedure ValidateAndShowError(const AName: string);
==== Dependency Injection ====
// TESTABILNO - Ovisnost injektirana
function ProcessFile(const APath: string; AFileReader: IFileReader): TResult;
// NIJE TESTABILNO - Hardkodirana ovisnost
function ProcessFile(const APath: string): TResult;
begin
Content := ReadFile(APath); // Ne može se mockirati
end;
===== Mocking =====
type
TMockFileReader = class(TInterfacedObject, IFileReader)
FContent: string;
function ReadFile(const APath: string): string;
end;
function TMockFileReader.ReadFile(const APath: string): string;
begin
Result := FContent; // Predefiniran sadržaj
end;
procedure TProcessorTest.TestProcessFile_ValidContent_Succeeds;
var
Mock: TMockFileReader;
Processor: TProcessor;
begin
Mock := TMockFileReader.Create;
Mock.FContent := 'test content';
Result := ProcessFile('any.txt', Mock);
CheckEquals('expected output', Result);
end;
===== Integration-Testovi =====
unit Integration.BuildPipeline.Tests;
procedure TBuildPipelineTest.TestFullBuild_ConsoleApp_ProducesExe;
var
Project: TWvdSProject;
Result: TWvdSBuildResult;
begin
// Setup
Project := CreateTestProject(ptConsole);
// Execute
Result := BuildProject(Project);
// Verify
CheckEquals(bsSuccess, Result.Status);
CheckTrue(FileExists(Result.OutputPath));
// Cleanup
DeleteTestProject(Project);
end;
===== E2E-Testovi =====
VS Code Extension Testing s @vscode/test-electron:
// test/extension.test.js (generirano iz Pascala)
const vscode = require('vscode');
const assert = require('assert');
suite('Extension Test Suite', () => {
test('Build command exists', async () => {
const commands = await vscode.commands.getCommands();
assert.ok(commands.includes('wvds.build.run'));
});
test('Build command executes', async () => {
await vscode.commands.executeCommand('wvds.build.run');
// Provjera da output channel sadrži očekivanu poruku
});
});
===== Izvršavanje testova =====
==== Lokalno ====
# Unit-Testovi
wvds-test unit
# Integration-Testovi
wvds-test integration
# Svi testovi
wvds-test all
==== CI ====
test:
runs-on: ubuntu-latest
steps:
- name: Run Unit Tests
run: wvds-test unit --report junit
- name: Run E2E Tests
run: wvds-test e2e --report junit
- name: Upload Results
uses: actions/upload-artifact@v3
with:
name: test-results
path: binaries/logs/test-*.xml
===== Code Coverage =====
wvds-test unit --coverage
# Generira:
# binaries/logs/coverage.html
# binaries/logs/coverage.json
**Minimalna Coverage:**
* Services: 80%
* Models: 90%
* Utilities: 70%
===== Vidi također =====
* [[.:debugging|Debugging]]
* [[.:build-pipeline|Build-Pipeline]]
* [[.:code-konventionen|Konvencije koda]]