Eng yaxshi amaliyotlarga o'ting - sinov

Dasturlash faoliyatimning dastlabki kunlaridanoq men ahamiyatni ko'rmaganman va asosan bu ish takrorlangan deb o'ylagandim. Endi men odatda yozganlarimning 90-100 foizini qamrab olishga intilaman. Va men odatda har bir qavatda sinov o'tkazish yaxshi amaliyot ekanligiga ishonaman (bunga yana qaytamiz)

Haqiqatdan ham, har kuni oldimda turgan kod bazalariga qaraganimda, eng ko'p o'zgartiradigan qo'rquvlarim, test sinovlari kam bo'lganlardir. Va bu oxir-oqibat mening mahsuldorligimni va etkazib berish narxlarimizni pasaytiradi. Shuning uchun menga shunisi aniqki, yuqori sinov qamrovi yuqori sifat va yuqori mahsuldorlikni tenglashtiradi.

Har bir qavatda sinov

Biz darhol misolga sho'ng'iymiz. Sizda quyidagi tuzilishga ega ilova bor deylik.

Ilova modeli

Modellar va ishlov beruvchilar kabi bir nechta umumiy komponentlar mavjud. Keyin ushbu ilova bilan o'zaro ishlashning turli xil usullari mavjud, masalan. CLI, HTTP API yoki Thrift RPC-lar. Siz nafaqat modellarni yoki faqat ishlov beruvchilarni, balki barchasini sinab ko'rganingizga ishonch hosil qilish uchun yaxshi amaliyot deb topdim. Hatto bir xil xususiyat uchun ham. Chunki, agar ishlov beruvchida Feature X-ni qo'llab-quvvatlagan bo'lsangiz, masalan, HTTP va Thrift interfeyslari orqali mavjudligi aniq.

Bu siz mantiqqa o'zgartirishlar kiritishda, hatto dasturning tubida chuqurroq o'zgarishlarga amin bo'lasiz.

Jadval asosida testlar

Biror usulni sinab ko'rishda deyarli barcha holatlarda siz funktsiyada bir nechta stsenariylarni sinab ko'rishni xohlaysiz. Odatda turli xil kirish parametrlari yoki turli xil masxarabozliklar bilan. Men ushbu testlarning barchasini bitta Test * funktsiyasiga birlashtirib, so'ng barcha sinov holatlarini ko'rib chiqishni yaxshi ko'raman. Asosiy misol:

TestDivision funktsiyasi (t * sinov.T) {
    testlar: = [] tizim {
        x float64
        y float64
        natija float64
        xato xatosi
    } {
        {x: 1.0, y: 2.0, natija: 0.5, xato: nol},
        {x: -1.0, y: 2.0, natija: -0.5, xato: nil},
        {x: 1.0, y: 0.0, natija: 0.0, xato: ErrZeroDivision},
    }
    uchun _, test: = oraliq testlar {
        natija, xato: = bo'lmoq (test.x, test.y)
        assert.IsType (t, test.err, err)
        tasdiqlash (sinov, natija, natija)
    }
}

Yuqoridagi testlar hamma narsani qamrab olmaydi, lekin kutilgan natijalar va xatolarni qanday sinash uchun namuna bo'lib xizmat qiladi. Yuqoridagi kod shuningdek tasdiqlash uchun ajoyib guvohlik to'plamidan foydalanadi.

Kengaytirilgan jadval jadvallari asosida nomlangan test holatlari

Agar sizda kodlar bazasi bilan tanish bo'lmagan ko'plab testlar yoki ko'pincha yangi ishlab chiquvchilar bo'lsa, testlaringizni nomlash foydali bo'lishi mumkin. Bu qanday ko'rinishga ega bo'lishining qisqacha namunasi

testlar: = xarita [string] tuzilish {
    son int
    smsErr xatosi
    xato xatosi
} {
    "muvaffaqiyatli": {0132423444, nil, nil},
    "xatoni targ'ib qiladi": {0132423444, sampleErr, sampleErr},
}

E'tibor bering, bu erda xarita va tilim o'rtasida farq bor. Xaritada buyurtma berilmaydi, tilim esa buyurtma bermaydi.

Istehzo bilan kulish

Interfeyslar, tabiiyki, sinovlar uchun juda yaxshi integratsiya nuqtasidir, chunki interfeysni osonlikcha soxtalashtirish bilan almashtirish mumkin. Biroq, masxara yozish juda zerikarli va zerikarli bo'lishi mumkin. Hayotimni osonlashtirish uchun men berilgan interfeys asosida masxara qilish uchun masxaralashdan foydalanaman.

Keling, u bilan qanday ishlashni ko'rib chiqaylik. Bizda quyidagi interfeys bor deylik.

SMS interfeysi turi {
    Yuborish (raqam int, matn qatori) xatosi
}

Mana shu interfeysdan foydalangan holda nodonlik

// Messager - bu har xil turdagi tizimli xabar almashish.
messager tipini {
    sms SMS
}
// SendHelloWorld dunyoga salom SMS xabarini yuboradi.
func (m * Messager) SendHelloWorld (son int) xatosi {
    xato: = m.sms.Send (raqam, "Salom, dunyo!")
    agar adashsangiz! = nil {
        qaytish xatosi
    }
    nil qaytaring
}

Endi biz SMS interfeys uchun masxara qilish uchun Mockery-dan foydalanishimiz mumkin. Mana bu ko'rinishi (bu misol interfeys bilan bir xil paketga joylashtiradigan -inpkg bayrog'idan foydalanadi).

// MockSMS - bu SMS turi uchun avtomatik ravishda yaratiladigan istehzo turi
turi MockSMS tuzilishi {
    masxara.Mock
}
// Yuborish berilgan maydonlar bilan soxta funktsiyani ta'minlaydi: raqam, matn
func (_m * MockSMS) Yuborish (son int, matn qatori) xatosi {
    ret: = _m.Qo'ng'iroqlar (raqam, matn)
    var r0 xatosi
    agar rf, ok: = ret.Get (0). (func (int, string) xatosi); ok {
        r0 = rf (raqam, matn)
    } else {
        r0 = qaytarish (xato) (0)
    }
    qaytish r0
}
var _ SMS = (* MockSMS) (nol)

SMS tuzilishi testify mock.Mock-dan meros bo'lib, test sinovlarini yozishda ba'zi qiziqarli variantlarni taqdim etadi. Shunday qilib, endi Mockery-dan istehzo bilan SendHelloWorld usuli uchun bizning sinovimizni yozish vaqti keldi.

Function TestSendHelloWorld (t * test.T) {
    sampleErr: = xatolar.Yangi ("ba'zi xatolar")
    testlar: = xarita [string] tuzilish {
        son int
        smsErr xatosi
        xato xatosi
    } {
        "muvaffaqiyatli": {0132423444, nil, nil},
        "xatoni targ'ib qiladi": {0132423444, sampleErr, sampleErr},
    }
    uchun _, test: = oraliq testlar {
        sms: = & MockSMS {}
        sms.On ("Yuborish", test.number, "Salom, dunyo!"). Qaytish (test.smsErr) .Once ()
        m: = & Xabarchi {
            sms: sms,
        }
   
        xato: = m.SendHelloWorld (test.number)
        tasdiqlash (tajriba, xato, xato)
        sms.AssertExpectations (t)
    }
}

Yuqoridagi misol kodida bir nechta fikrlarni aytib o'tish kerak. Sinovda, men MockSMS-ni biriktirib, keyin ishlatganimni sezasiz .On () yordamida ma'lum parametrlar soxtalashtirilganda nima bo'lishi kerakligini (. Qaytish () qaytarib bera olaman.

Va nihoyat, men sms.AssertExpectations-dan foydalanib, SMS-interfeysga kutilgan marta qo'ng'iroq qilishiga ishonch hosil qildim. Bunday holda, bir marta ().

Yuqoridagi barcha fayllarni ushbu jadvalda topish mumkin.

Oltin fayl sinovlari

Ba'zi hollarda men javoblar to'plami bir xil bo'lib qoladi, deb aytishni foydali deb topdim. Masalan, JSON ma'lumotlaridan API'dan olingan ma'lumotlar bo'lishi mumkin. Bu holda men Mishel Xashimotodan aqlli va kombinatsiyalangan oltin fayllardan foydalanish buyruqlar satrlari bayroqlarini sinovdan o'tkazish to'g'risida bilib oldim.

Asosiy fikr shundaki, siz faylga to'g'ri javob yozishingiz kerak (oltin fayl). Keyin testlarni bajarishda siz oltin fayl va test javobi o'rtasidagi baytni taqqoslaysiz.

Buni osonlashtirish uchun men buyruqlar satri bayroqchasini sozlash va oltin fayllarni yozish va taqqoslashni oshkora bajaradigan golddie to'plamini yaratdim.

Ushbu turdagi sinov uchun golfni qanday ishlatishga misol:

funktsiya TestExample (t * test.T) {
    yozuvchisi: = wikiptest.NewRecorder ()

    req, err: = http.NewRequest ("olish", "/ misol", nol)
    tasdiqlash.Nil (t, xato)

    ishlov beruvchi: = http.HandlerFunc (ExampleHandler)
    ishlov beruvchi.ServeHTTP ()

    goldie.Assert (t, "namuna", recorder.Body.Bytes ())
}

Oltin faylingizni yangilashingiz kerak bo'lganda quyidagilarni bajarasiz:

test-yangilanishga o'ting. / ...

Va siz shunchaki sinovlarni o'tkazmoqchi bo'lganingizda, odatdagidek shunday qilasiz:

sinovdan o'ting. / ...

Xayr!

Oxirigacha yopishganingiz uchun rahmat! Ushbu maqolada biron bir foydali narsa topdingiz deb umid qilaman.