Projekt zawiera testy jednostkowe napisane z użyciem Qt Test Framework. Testy pokrywają kluczowe funkcjonalności:
- Walidację danych wejściowych (URL, email, telefon)
- Szyfrowanie i deszyfrowanie haseł WiFi
- Qt6 z modułem Test
- CMake 3.16+
- Kompilator C++17
# Ubuntu/Debian
sudo apt install qt6-base-dev libqt6test6
# Arch Linux
sudo pacman -S qt6-base
# Fedora
sudo dnf install qt6-qtbase-develmkdir build && cd build
cmake ..
makecmake -DBUILD_TESTS=OFF ..
makecd build
ctest --output-on-failurePrzykładowe wyjście:
Test project /home/user/QR_Generator/build
Start 1: ValidationTests
1/2 Test #1: ValidationTests .................. Passed 0.12 sec
Start 2: EncryptionTests
2/2 Test #2: EncryptionTests .................. Passed 0.34 sec
100% tests passed, 0 tests failed out of 2
./test_validationPrzykładowe wyjście:
********* Start testing of TestValidation *********
Config: Using QtTest library 6.x.x
PASS : TestValidation::initTestCase()
PASS : TestValidation::testValidUrl(simple https)
PASS : TestValidation::testValidUrl(with path)
PASS : TestValidation::testInvalidUrl(empty)
PASS : TestValidation::testValidEmail(simple)
PASS : TestValidation::testInvalidEmail(no @)
PASS : TestValidation::cleanupTestCase()
Totals: 25 passed, 0 failed, 0 skipped, 0 blacklisted, 234ms
********* Finished testing of TestValidation *********
./test_encryptionPrzykładowe wyjście:
********* Start testing of TestEncryption *********
Config: Using QtTest library 6.x.x
PASS : TestEncryption::initTestCase()
PASS : TestEncryption::testEncryptDecrypt(simple)
PASS : TestEncryption::testEmptyPassword()
PASS : TestEncryption::testUnicodePassword()
PASS : TestEncryption::testLongPassword()
PASS : TestEncryption::testSaltUniqueness()
PASS : TestEncryption::cleanupTestCase()
Totals: 12 passed, 0 failed, 0 skipped, 0 blacklisted, 456ms
********* Finished testing of TestEncryption *********
Testowane przypadki:
- ✅ Poprawne URL: https://example.com, http://192.168.1.1
- ✅ URL z parametrami: https://example.com?param=value
- ✅ URL z portem: https://example.com:8080
- ❌ Niepoprawne: puste, ze spacjami, bez domeny
Przykładowy test:
void TestValidation::testValidUrl() {
QFETCH(QString, url);
QVERIFY2(m_generator->isValidUrl(url),
qPrintable(QString("URL should be valid: %1").arg(url)));
}Testowane przypadki:
- ✅ Poprawne: user@example.com, user.name@mail.example.com
- ✅ Pusty email (opcjonalny)
- ❌ Niepoprawne: brak @, podwójny @, bez domeny
Testowane przypadki:
- ✅ Formaty międzynarodowe: +48 123 456 789, (48) 123-456-789
- ✅ Pusty numer (opcjonalny)
- ❌ Niepoprawne: litery, za krótkie, znaki specjalne
Testowane przypadki:
- Proste hasła: "password123"
- Znaki specjalne: "p@ssw0rd!#$%"
- Spacje: "my password 123"
- Unicode: "Zażółć gęślą jaźń 日本語"
- Długie hasła (>64 znaki)
Test:
void TestEncryption::testEncryptDecrypt() {
QFETCH(QString, password);
QString encrypted;
QMetaObject::invokeMethod(m_generator, "encryptPassword",
Qt::DirectConnection,
Q_RETURN_ARG(QString, encrypted),
Q_ARG(QString, password));
QString decrypted;
QMetaObject::invokeMethod(m_generator, "decryptPassword",
Qt::DirectConnection,
Q_RETURN_ARG(QString, decrypted),
Q_ARG(QString, encrypted));
QCOMPARE(decrypted, password);
}Test: Dwukrotne zaszyfrowanie tego samego hasła powinno dać różne wyniki (losowy salt)
void TestEncryption::testSaltUniqueness() {
QString password = "test123";
QString encrypted1 = encryptPassword(password);
QString encrypted2 = encryptPassword(password);
// Różne zaszyfrowane wartości
QVERIFY2(encrypted1 != encrypted2, "Salt should be random");
// Ale oba deszyfrują się do tego samego
QCOMPARE(decryptPassword(encrypted1), password);
QCOMPARE(decryptPassword(encrypted2), password);
}Dla bardziej szczegółowego wyjścia:
# Wszystkie testy z pełnymi logami
ctest --verbose
# Pojedynczy test z debugiem
./test_validation -v2
# Z funkcjami debugowania Qt
QT_LOGGING_RULES="*.debug=true" ./test_validationAby zmierzyć pokrycie testami:
mkdir build-coverage && cd build-coverage
cmake -DCMAKE_CXX_FLAGS="--coverage" -DCMAKE_BUILD_TYPE=Debug ..
makectest# Instalacja lcov
sudo apt install lcov # Ubuntu/Debian
sudo pacman -S lcov # Arch Linux
# Generowanie raportu
lcov --capture --directory . --output-file coverage.info
lcov --remove coverage.info '/usr/*' '*/tests/*' --output-file coverage_filtered.info
genhtml coverage_filtered.info --output-directory coverage_html
# Otwórz w przeglądarce
xdg-open coverage_html/index.htmlOczekiwane pokrycie:
- Walidacja: ~95%
- Szyfrowanie: ~90%
- Całość: ~70% (wiele kodu UI jest trudne do przetestowania)
Utwórz .github/workflows/tests.yml:
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y qt6-base-dev libqrencode-dev libopencv-dev
- name: Build
run: |
mkdir build && cd build
cmake ..
make
- name: Run tests
run: |
cd build
ctest --output-on-failure#include <QtTest/QtTest>
#include "qrgenerator.h"
class TestNewFeature : public QObject
{
Q_OBJECT
private slots:
void initTestCase(); // Przed wszystkimi testami
void init(); // Przed każdym testem
void testSomething(); // Twój test
void cleanup(); // Po każdym teście
void cleanupTestCase(); // Po wszystkich testach
private:
QRGenerator* m_generator;
};
void TestNewFeature::initTestCase() {
m_generator = new QRGenerator();
}
void TestNewFeature::testSomething() {
// Arrange
QString input = "test data";
// Act
QString result = m_generator->someMethod(input);
// Assert
QCOMPARE(result, "expected");
QVERIFY(!result.isEmpty());
}
QTEST_MAIN(TestNewFeature)
#include "test_new_feature.moc"# W sekcji BUILD_TESTS
add_executable(test_new_feature tests/test_new_feature.cpp)
target_link_libraries(test_new_feature PRIVATE qrgenerator_lib Qt6::Test)
add_test(NAME NewFeatureTests COMMAND test_new_feature)gdb ./test_validation
(gdb) run
(gdb) bt # backtrace gdy test failujevalgrind --leak-check=full ./test_validation- Otwórz projekt w Qt Creator
- Przejdź do "Projects" → "Build & Run" → "Test"
- Kliknij prawym na test → "Debug test"
error: no member named 'isValidUrl' in 'QRGenerator'
Rozwiązanie: Upewnij się, że metoda jest publiczna lub dodaj friend class TestValidation; do klasy.
FAIL! : TestValidation::testValidUrl(simple https) Compared values are not the same
Rozwiązanie: Sprawdź dane testowe (_data() funkcja) i warunki QCOMPARE.
- Sprawdź różnice w wersjach Qt
- Upewnij się, że wszystkie zależności są zainstalowane
- Sprawdź różnice w locale (np. formaty dat)
Dla testów wydajności dodaj:
void TestEncryption::benchmarkEncryption() {
QString password = "test_password_123";
QBENCHMARK {
QString encrypted = encryptPassword(password);
}
}Uruchom:
./test_encryption -tickcounter- Oficjalna dokumentacja: https://doc.qt.io/qt-6/qtest-overview.html
- Tutorial: https://doc.qt.io/qt-6/qtest-tutorial.html
- Makra testowe: https://doc.qt.io/qt-6/qtest.html
Uwaga: Testy są automatycznie uruchamiane jeśli BUILD_TESTS=ON (domyślnie). Dla release builds możesz wyłączyć testy używając -DBUILD_TESTS=OFF.
Dokument utworzony: 2025-11-18 Ostatnia aktualizacja: 2025-11-18