Skip to content

استراتيجية الاختبار — نظام إدارة المغسلة

معلومات الوثيقة

الحقل القيمة
المشروع نظام إدارة المغسلة
الإصدار 1.0
اللغة العربية
نوع الوثيقة استراتيجية الاختبار وضمان الجودة

1. هرم الاختبارات

الطبقة النسبة الأداة التغطية المستهدفة
وحدة 70% xUnit (خلفية)، Jest (واجهة) ≥ 80% إجمالي
تكامل 20% TestContainers (خلفية)، TestBed (واجهة) 100% للمسارات الحرجة
يدوي / E2E 10% قائمة تدقيق Tauri يدوية جميع الميزات لكل إصدار

2. اختبارات الخلفية (xUnit + TestContainers)

اختبارات الوحدة

[Fact]
public void Evaluate_InvoiceCreated_PaidByCash_ReturnsCorrectEntries()
{
    var engine = new AccountingRulesEngine(GetTestRules());
    var invoice = CreateTestInvoice(grandTotal: 150.00m);
    var entries = engine.Evaluate("InvoiceCreated", invoice, PaymentMethod.Cash);

    entries.Should().HaveCount(2);
    entries[0].AccountCode.Should().Be("1000");   // نقدية
    entries[0].Debit.Should().Be(150.00m);
    entries[1].AccountCode.Should().Be("4000");    // إيراد غسيل
    entries[1].Credit.Should().Be(150.00m);
}

اختبارات تكاملية مع TestContainers

public class InvoiceIntegrationTests : IAsyncLifetime
{
    private readonly PostgreSqlContainer _postgres =
        new PostgreSqlBuilder().WithDatabase("laundry_test").Build();

    [Fact]
    public async Task CreateInvoice_WithPayment_SavesInvoiceAndPostsToGL()
    {
        var result = await CreateHandler().Handle(new CreateInvoiceCommand(...), ct);
        result.IsSuccess.Should().BeTrue();

        var glLines = await GetGlLinesForInvoice(result.Value.Id);
        glLines.Sum(x => x.Debit).Should().Be(glLines.Sum(x => x.Credit));
    }
}

سيناريوهات الاختبار الأساسية

  • المصادقة: دخول ناجح، كلمة مرور خاطئة، رمز منتهٍ، دور مفقود
  • الفاتورة: مسودة، تأكيد، تغيير حالة، إلغاء، منع تكرار الرقم
  • الدفع: فردي، متعدد الطرق، جزئي، رفض دفع زائد
  • المحاسبة: جميع التدفقات الـ 13 تولد قيوداً صحيحة
  • السجاد: إيصال ← فاتورة نهائية، خصم عربون، فائض رصيد
  • الخياطة: تعيين خياط، تسجيل تكلفة، حساب المستحقات
  • الترخيص: ساري، سماح، إيقاف تام، ملف تالف
  • المزامنة: تصدير، استيراد، تكرار الاستيراد

3. اختبارات الواجهة (Jest + TestBed)

اختبار مكون

describe('InvoiceListContainer', () => {
  it('يجب عرض الفواتير من المتجر', () => {
    store.overrideSelector(selectAllInvoices, [{ id: '1', invoiceNumber: 'INV-001' }]);
    store.refreshState();
    fixture.detectChanges();
    expect(fixture.nativeElement.textContent).toContain('INV-001');
  });
});

اختبار خدمة

it('يجب استدعاء GET /api/invoices', () => {
  service.getAll().subscribe(invoices => expect(invoices.length).toBe(2));
  const req = httpMock.expectOne('/api/invoices');
  req.flush([{ id: '1' }, { id: '2' }]);
});

اختبار NgRx Effects

it('يجب إرجاع loadSuccess عند النجاح', (done) => {
  service.getAll.mockReturnValue(of([{ id: '1' }]));
  actions$ = of(InvoiceActions.load());
  effects.load$.subscribe(result => {
    expect(result).toEqual(InvoiceActions.loadSuccess({ invoices: [{ id: '1' }] }));
    done();
  });
});

4. اختبار تكامل Tauri

import { mockIPC } from '@tauri-apps/api/mocks';

mockIPC((cmd) => {
  switch (cmd) {
    case 'compute_client_token': return 'test-token-abc123';
    case 'start_docker_services': return 'OK';
  }
});

it('يجب حساب رمز العميل', async () => {
  const token = await service.computeClientToken();
  expect(token).toBe('test-token-abc123');
});

5. اختبارات التحقق المحاسبي

كل تدفق محاسبي يجب أن يجتاز اختبار القاعدة الذهبية:

[Theory]
[ClassData(typeof(AccountingScenarioProvider))]
public void AccountingFlow_Always_Balances(string scenario, Func<Task<Guid>> act)
{
    var referenceId = await act();
    var glLines = await GetGlLinesForReference(referenceId);
    var totalDebit = glLines.Sum(x => x.Debit);
    var totalCredit = glLines.Sum(x => x.Credit);

    totalDebit.Should().Be(totalCredit,
        $"السيناريو '{scenario}' أنتج قيوداً غير متوازنة");
}

تشمل السيناريوهات الـ 17: فاتورة نقدية، آجلة، جزئية، مع مخزون، عربون سجاد، فاتورة نهائية بفائض/نقص، نماذج تسوية الشركات الثلاثة، نماذج دفع الخياطين الثلاثة، تعويض نقدي/دائن، استرداد، إلغاء.

6. اختبارات المزامنة

[Fact]
public async Task ExportImport_RoundTrip_ProducesIdenticalData()
{
    // إنشاء بيانات ← تصدير ← استيراد ← تعداد الصفوف متطابق
    var result = await importService.ImportAsync(syncFile);
    centralCount.Should().Be(offlineCount);
}

[Fact]
public async Task Reimport_SameFile_Twice_IsIdempotent()
{
    await importService.ImportAsync(syncFile);
    var result = await importService.ImportAsync(syncFile);
    result.RowsImported.Should().Be(0);  // لم يستورد شيئاً
}

7. متطلبات تغطية الكود

الطبقة الأداة الحد الأدنى المستهدف
وحدة الخلفية coverlet 80% 90%
تكامل الخلفية coverlet 100% للتدفقات المحاسبية
وحدة الواجهة Jest 70% 85%

8. تنفيذ الاختبار في CI

- run: dotnet test --no-build -c Release --collect:"XPlat Code Coverage"
- run: npm test -- --watch=false --coverage --ci
- name: التحقق من حدود التغطية
  run: reportgenerator -reports:**/coverage.cobertura.xml

9. قائمة التدقيق اليدوي — Tauri

تنفذ قبل كل GitHub Release على المنصات الثلاث:

التثبيت

  • [ ] تثبيت من .msi / .dmg / .deb
  • [ ] أول تشغيل يظهر المعالج
  • [ ] إنشاء مسؤول بكلمة مرور تلقائية ومخصصة

الأساسيات

  • [ ] إنشاء فاتورة: إضافة بنود، اختيار قطعة وخدمة، تأكيد
  • [ ] مسودة ← مؤكدة ← جاهزة ← مسلّمة
  • [ ] بطاقات باركود تولد وتطبع
  • [ ] دفع: نقدي، بطاقة، متعدد، جزئي
  • [ ] بحث عن الفواتير
  • [ ] وردية: فتح ← مبيعات ← إغلاق ← فروقات

السجاد والخياطة

  • [ ] إيصال سجاد ← فاتورة نهائية
  • [ ] 3 استراتيجيات تسعير
  • [ ] طلب خياطة مع تعيين خياط
  • [ ] تقرير مستحقات

سطح المكتب

  • [ ] فتح المتصفح يعرض 403 (الفرع غير المتصل)
  • [ ] انتهاء الترخيص: شريط أحمر (أيام 1-7)
  • [ ] إيقاف تام: الكتابة ممنوعة (يوم 8+)
  • [ ] استبدال license.dat: يستعيد التطبيق

الطباعة والتصدير

  • [ ] طباعة حرارية على ورق 80mm
  • [ ] طباعة A4
  • [ ] تصدير Excel و PDF

سجل المراجعة

التاريخ الإصدار المعد التغييرات
2026-05-10 1.0 قائد الجودة الإصدار الأولي لاستراتيجية الاختبار