JavaRush /Blog Jawa /Random-JV /Tes Unit Jawa: teknik, konsep, praktik

Tes Unit Jawa: teknik, konsep, praktik

Diterbitake ing grup
Dina iki, sampeyan meh ora bakal nemokake aplikasi sing ora kalebu tes, mula topik iki bakal luwih relevan tinimbang sadurunge kanggo pangembang pemula: tanpa tes sampeyan ora bisa tekan ngendi wae. Minangka pariwara, aku saranake sampeyan ndeleng artikelku sing kepungkur. Sawetara tes kalebu tes (lan uga artikel kasebut bakal migunani banget):
  1. Pengujian integrasi database nggunakake MariaDB kanggo ngganti MySql
  2. Implementasi aplikasi multibahasa
  3. Nyimpen file menyang aplikasi lan data babagan menyang database
Ayo dipikirake apa jinis tes sing digunakake ing prinsip, lan sawise iku kita bakal sinau kanthi rinci kabeh sing sampeyan kudu ngerti babagan tes unit.

Jinis tes

Apa iku tes? Kaya sing dikandhakake Wiki: " Tes utawa nyoba minangka cara kanggo nyinaoni proses dhasar saka sistem kanthi nempatake sistem ing kahanan sing beda-beda lan nglacak owah-owahan sing bisa dideleng." Ing tembung liya, iki minangka tes operasi sing bener saka sistem kita ing kahanan tartamtu. Kabeh babagan Pengujian Unit: metode, konsep, praktik - 2Inggih, ayo ndeleng apa jinis tes sing ana:
  1. Pengujian unit yaiku tes sing tugase kanggo nguji saben modul sistem kanthi individu. Iku seng di pengeni sing iki bêsik minimally dibagi saka sistem, contone, modul.

  2. Pengujian sistem minangka tes tingkat dhuwur kanggo nguji operasi saka aplikasi utawa sistem kanthi sakabehe.

  3. Pengujian regresi yaiku tes sing digunakake kanggo mriksa apa fitur anyar utawa koreksi bug mengaruhi fungsi aplikasi sing wis ana lan manawa bug lawas katon maneh.

  4. Pengujian fungsional yaiku mriksa kepatuhan bagean aplikasi kanthi syarat sing kasebut ing spesifikasi, crita pangguna, lsp.

    Jenis tes fungsional:

    • Tes "kotak putih" kanggo netepi bagean aplikasi kanthi syarat kanthi kawruh babagan implementasi internal sistem;
    • "Kothak ireng" test kanggo selaras karo bagean saka aplikasi karo syarat tanpa kawruh saka implementasine internal saka sistem.
  5. Tes kinerja minangka jinis tes sing ditulis kanggo nemtokake kacepetan sistem utawa bagean kasebut mlaku ing beban tartamtu.
  6. Tes beban - tes sing dirancang kanggo mriksa stabilitas sistem ing beban standar lan nemokake puncak maksimal sing bisa digunakake kanthi bener.
  7. Pengujian stres minangka jinis tes sing dirancang kanggo mriksa fungsionalitas aplikasi ing beban sing ora standar lan kanggo nemtokake puncak maksimal sing sistem ora bakal nabrak.
  8. Tes keamanan - tes sing digunakake kanggo mriksa keamanan sistem (saka serangan peretas, virus, akses ora sah menyang data rahasia lan kesenengan urip liyane).
  9. Pengujian lokalisasi yaiku pangujian lokalisasi kanggo aplikasi.
  10. Tes usability minangka jinis tes sing dituju kanggo mriksa kegunaan, pemahaman, daya tarik lan sinau kanggo pangguna.
  11. Iki kabeh muni apik, nanging carane iku bisa ing laku? Iku prasaja: Mike Cohn testing piramida digunakake: Kabeh babagan Pengujian Unit: metode, konsep, praktik - 4Iki versi simplified saka piramida: saiki dipérang dadi bagéan cilik. Nanging dina iki kita ora bakal pervert lan nimbang pilihan sing paling gampang.
    1. Unit - tes unit sing digunakake ing macem-macem lapisan aplikasi, nguji logika aplikasi sing paling cilik sing bisa dibagi: contone, kelas, nanging paling asring cara. Tes kasebut biasane nyoba ngisolasi saka logika eksternal, yaiku, kanggo nggawe ilusi manawa aplikasi liyane digunakake ing mode standar.

      Mesthi ana akeh tes kasebut (luwih saka jinis liyane), amarga padha nyoba potongan-potongan cilik lan entheng banget, ora akeh sumber daya (dening sumber daya tegese RAM lan wektu).

    2. Integrasi - testing integrasi. Iku mriksa bagéyan luwih gedhe saka sistem, sing, iku salah siji kombinasi saka sawetara bagéyan logika (sawetara cara utawa kelas), utawa bener nggarap komponen external. Biasane tes kasebut luwih sithik tinimbang tes Unit, amarga luwih abot.

      Minangka conto tes integrasi, sampeyan bisa nimbang nyambungake menyang database lan mriksa yen cara sing bisa digunakake kanthi bener .

    3. UI - tes sing mriksa operasi antarmuka panganggo. Padha mengaruhi logika ing kabeh tingkat saka aplikasi, kang uga disebut end-to-end. Minangka aturan, ana akeh kurang saka wong-wong mau, amarga padha sing paling abot lan kudu mriksa paling perlu (digunakake) dalan.

      Ing gambar ing ndhuwur, kita ndeleng rasio wilayah saka macem-macem bagean saka segi telu: kira-kira proporsi sing padha dijaga ing jumlah tes kasebut ing karya nyata.

      Dina iki kita bakal nliti tes sing paling akeh digunakake - tes unit, amarga kabeh pangembang Java sing ngurmati awake dhewe kudu bisa digunakake ing tingkat dhasar.

    Konsep utama saka testing unit

    Jangkoan tes (Cakupan Kode) minangka salah sawijining penilaian utama babagan kualitas tes aplikasi. Iki minangka persentase kode sing dilindhungi dening tes (0-100%). Ing laku, akeh wong ngoyak persentase iki, sing aku ora setuju, amarga wiwit nambah tes sing ora dibutuhake. Contone, layanan kita duwe operasi CRUD standar (nggawe / njaluk / nganyari / mbusak) tanpa logika tambahan. Cara iki sejatine perantara sing utusan karya menyang lapisan sing bisa digunakake karo repositori. Ing kahanan iki, kita ora duwe apa-apa kanggo nyoba: mbok menawa cara iki nelpon cara saka Tao, nanging iki ora serius. Kanggo netepake jangkoan tes, alat tambahan biasane digunakake: JaCoCo, Cobertura, Clover, Emma, ​​​​etc. Kanggo sinau sing luwih rinci babagan masalah iki, simpen sawetara artikel sing cocog: TDD (Test-driven development) - pangembangan test-driven. Ing pendekatan iki, pisanan kabeh, test ditulis sing bakal mriksa kode tartamtu. Pranyata metu dadi testing kothak ireng: kita ngerti apa ing input lan kita ngerti apa sing kudu kelakon ing output. Iki ngindhari duplikasi kode. Pangembangan adhedhasar uji coba diwiwiti kanthi ngrancang lan ngembangake tes kanggo saben fungsi cilik aplikasi kasebut. Ing pendekatan TDD, pisanan, tes dikembangake sing nemtokake lan verifikasi apa sing bakal ditindakake kode kasebut. Tujuan utama TDD yaiku nggawe kode luwih jelas, luwih gampang, lan bebas kesalahan. Kabeh babagan Pengujian Unit: metode, konsep, praktik - 6Pendekatan kasebut kalebu komponen ing ngisor iki:
    1. Kita nulis tes kita.
    2. Kita nindakake tes kasebut, manawa lulus utawa ora (kita weruh yen kabeh abang - aja wedi: iki kudune).
    3. We nambah kode sing kudu gawe marem test iki (run test).
    4. We refactor kode.
    Adhedhasar kasunyatan manawa tes unit minangka unsur paling cilik ing piramida otomatisasi tes, TDD adhedhasar. Kanthi bantuan tes unit, kita bisa nyoba logika bisnis kelas apa wae. BDD (Behavior-driven development) - pangembangan liwat prilaku. Pendekatan iki adhedhasar TDD. Luwih khusus, nggunakake conto sing ditulis nganggo basa sing cetha (biasane ing basa Inggris) sing nggambarake prilaku sistem kanggo kabeh wong sing melu pembangunan. Kita ora bakal luwih jero babagan istilah iki, amarga utamane mengaruhi penguji lan analis bisnis. Test Case - script sing njlèntrèhaké langkah-langkah, kahanan tartamtu lan paramèter sing perlu kanggo verifikasi implementasine saka kode ing test. Perlengkapan minangka kahanan lingkungan tes sing dibutuhake kanggo sukses eksekusi metode sing diuji. Iki minangka set obyek sing wis ditemtokake lan prilaku ing kahanan sing digunakake.

    Tahap tes

    Tes kasebut kasusun saka telung tahap:
    1. Nemtokake data sing bakal diuji (perlengkapan).
    2. Nggunakake kode sing diuji (nelpon metode sing diuji).
    3. Priksa asil lan mbandhingake karo sing dikarepake.
    Kabeh babagan Pengujian Unit: metode, konsep, praktik - 7Kanggo njamin modularitas tes, sampeyan kudu diisolasi saka lapisan aplikasi liyane. Iki bisa ditindakake kanthi nggunakake rintisan, mock lan spy. Mocks minangka obyek sing bisa dikustomisasi (contone, khusus kanggo saben tes) lan ngidini sampeyan nyetel pangarepan kanggo telpon metode ing bentuk tanggapan sing bakal ditampa. Priksa pangarepan ditindakake liwat telpon menyang obyek Mock. Rintisan - menehi respon kabel hard kanggo telpon sak testing. Dheweke uga bisa nyimpen informasi babagan telpon (contone, paramèter utawa nomer telpon kasebut). Iki kadhangkala disebut kanthi istilah dhewe - spy ( Spy ). Kadhangkala istilah rintisan lan moyoki iki bingung: prabédan iku stub ora mriksa apa-apa, nanging mung simulates negara tartamtu. Mock minangka obyek sing nduweni pangarep-arep. Contone, yen cara kelas tartamtu kudu disebut kaping tartamtu. Ing tembung liya, tes sampeyan ora bakal rusak amarga ana rintisan, nanging bisa uga rusak amarga dipoyoki.

    Lingkungan Tes

    Dadi saiki ayo padha mudhun menyang bisnis. Ana sawetara lingkungan testing (kerangka) kasedhiya kanggo Jawa. Sing paling populer yaiku JUnit lan TestNG. Kanggo review kita, kita nggunakake: Kabeh babagan Pengujian Unit: metode, konsep, praktik - 8A test JUnit minangka cara sing ana ing kelas sing mung digunakake kanggo testing. Kelas biasane dijenengi padha karo kelas sing dites karo + Test ing pungkasan. Contone, CarService→ CarServiceTest. Sistem mbangun Maven kanthi otomatis kalebu kelas kasebut ing area tes. Nyatane, kelas iki diarani kelas tes. Ayo dadi liwat anotasi dhasar sethithik: @Test - definisi metode iki minangka metode tes (nyatane, metode sing ditandhani karo anotasi iki minangka tes unit). @Sadurunge - menehi tandha cara sing bakal ditindakake sadurunge saben tes. Contone, ngisi data test kelas, maca data input, lan liya-liyane @After - diselehake ing ndhuwur cara sing bakal diarani sawise saben test (data reresik, mulihake nilai standar). @BeforeClass - diselehake ing ndhuwur metode - analog karo @Before. Nanging cara iki diarani mung sapisan sadurunge kabeh tes kanggo kelas tartamtu lan mulane kudu statis. Iki digunakake kanggo nindakake operasi tugas sing luwih abot, kayata ngangkat database tes. @AfterClass minangka kebalikan saka @BeforeClass: dieksekusi sapisan kanggo kelas tartamtu, nanging dieksekusi sawise kabeh tes. Digunakake, contone, kanggo ngresiki sumber daya terus-terusan utawa medhot saka database. @Ignore - cathetan sing cara ing ngisor iki dipatèni lan bakal digatèkaké nalika mbukak tes sakabèhé. Iki digunakake ing macem-macem kasus, contone, yen cara dhasar diganti lan ora ana wektu kanggo mbaleni tes kasebut. Ing kasus kaya mengkono, iku uga saranake kanggo nambah katrangan - @Ignore("Sawetara gambaran"). @Test (dikarepake = Exception.class) - digunakake kanggo tes negatif. Iki minangka tes sing mriksa cara tumindak yen ana kesalahan, yaiku, tes kasebut ngarepake metode kasebut bakal mbuwang sawetara pangecualian. Cara kasebut dilambangake karo anotasi @Test, nanging kanthi kesalahan kanggo nyekel. @Test (wektu entek = 100) - mriksa manawa metode kasebut dieksekusi ora luwih saka 100 milidetik. @Mock - kelas digunakake liwat lapangan kanggo nyetel obyek diwenehi minangka mock (iki ora saka perpustakaan Junit, nanging saka Mockito), lan yen kita perlu, kita bakal nyetel prilaku mock ing kahanan tartamtu. , langsung ing cara tes. @RunWith (MockitoJUnitRunner.class) - cara diselehake ing ndhuwur kelas. Iki tombol kanggo mbukak tes ing. Pelari bisa beda-beda: contone, ana ing ngisor iki: MockitoJUnitRunner, JUnitPlatform, SpringRunner, lsp). Ing JUnit 5, anotasi @RunWith diganti karo anotasi @ExtendWith sing luwih kuat. Ayo goleki sawetara cara kanggo mbandhingake asil:
    • assertEquals(Object expecteds, Object actuals)- mriksa apa obyek sing ditularake padha.
    • assertTrue(boolean flag)- mriksa apa nilai liwati bali bener.
    • assertFalse(boolean flag)- mriksa apa nilai liwati bali palsu.
    • assertNull(Object object)– mriksa apa obyek iku null.
    • assertSame(Object firstObject, Object secondObject)- mriksa apa nilai sing dilewati nuduhake obyek sing padha.
    • assertThat(T t, Matcher<T> matcher)- mriksa apa t gawe marem kondisi kasebut ing matcher.
    Ana uga wangun comparison migunani saka assertj - assertThat(firstObject).isEqualTo(secondObject) Kene aku ngedika bab cara dhasar, wiwit liyane variasi beda saka ndhuwur.

    Praktek tes

    Saiki ayo ndelok materi ing ndhuwur nggunakake conto tartamtu. Kita bakal nyoba cara kanggo layanan - nganyari. Kita ora bakal nganggep lapisan dao, amarga iku standar kita. Ayo nambah wiwitan kanggo tes:
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <version>2.2.2.RELEASE</version>
       <scope>test</scope>
    </dependency>
    Dadi, kelas layanan:
    @Service
    @RequiredArgsConstructor
    public class RobotServiceImpl implements RobotService {
       private final RobotDAO robotDAO;
    
       @Override
       public Robot update(Long id, Robot robot) {
           Robot found = robotDAO.findById(id);
           return robotDAO.update(Robot.builder()
                   .id(id)
                   .name(robot.getName() != null ? robot.getName() : found.getName())
                   .cpu(robot.getCpu() != null ? robot.getCpu() : found.getCpu())
                   .producer(robot.getProducer() != null ? robot.getProducer() : found.getProducer())
                   .build());
       }
    }
    8 - narik obyek sing dianyari saka database 9-14 - nggawe obyek liwat pembangun, yen obyek sing mlebu duwe lapangan - nyetel, yen ora - ninggalake apa sing ana ing database Lan ndeleng test kita:
    @RunWith(MockitoJUnitRunner.class)
    public class RobotServiceImplTest {
       @Mock
       private RobotDAO robotDAO;
    
       private RobotServiceImpl robotService;
    
       private static Robot testRobot;
    
       @BeforeClass
       public static void prepareTestData() {
           testRobot = Robot
                   .builder()
                   .id(123L)
                   .name("testRobotMolly")
                   .cpu("Intel Core i7-9700K")
                   .producer("China")
                   .build();
       }
    
       @Before
       public void init() {
           robotService = new RobotServiceImpl(robotDAO);
       }
    1 — Runner 4 kita — ngisolasi layanan saka lapisan dao kanthi ngganti mock 11 — nyetel entitas test kanggo kelas (sing bakal digunakake minangka hamster test) 22 — nyetel obyek layanan sing bakal dites
    @Test
    public void updateTest() {
       when(robotDAO.findById(any(Long.class))).thenReturn(testRobot);
       when(robotDAO.update(any(Robot.class))).then(returnsFirstArg());
       Robot robotForUpdate = Robot
               .builder()
               .name("Vally")
               .cpu("AMD Ryzen 7 2700X")
               .build();
    
       Robot resultRobot = robotService.update(123L, robotForUpdate);
    
       assertNotNull(resultRobot);
       assertSame(resultRobot.getId(),testRobot.getId());
       assertThat(resultRobot.getName()).isEqualTo(robotForUpdate.getName());
       assertTrue(resultRobot.getCpu().equals(robotForUpdate.getCpu()));
       assertEquals(resultRobot.getProducer(),testRobot.getProducer());
    }
    Ing kene kita ndeleng divisi sing jelas saka tes dadi telung bagean: 3-9 - nyetel perlengkapan 11 - nglakokake bagean sing diuji 13-17 - mriksa asil Rincian liyane: 3-4 - nyetel prilaku kanggo moka dao 5 - nyetel conto sing bakal dianyari ing ndhuwur standar 11 - gunakake metode kasebut lan njupuk conto asil 13 - priksa manawa ora nol 14 - priksa ID asil lan argumen metode sing ditemtokake 15 - priksa manawa jeneng wis dianyari 16 - katon ing asil dening cpu 17 - amarga kita ora nyetel iki ing lapangan Kayata nganyari, iku kudu tetep padha, ayo kang mriksa. Kabeh babagan Pengujian Unit: metode, konsep, praktik - 9Ayo diluncurake: Kabeh babagan Pengujian Unit: teknik, konsep, praktik - 10Tes kasebut ijo, sampeyan bisa ngobati)) Dadi, ayo ngringkes: tes nambah kualitas kode lan nggawe proses pangembangan luwih fleksibel lan dipercaya. Mbayangno carane akeh gaweyan kita kudu nglampahi nalika redesigning lunak karo atusan file kelas. Sawise kita duwe tes unit sing ditulis kanggo kabeh kelas kasebut, kita bisa refactor kanthi yakin. Lan sing paling penting, mbantu gampang nemokake kesalahan sajrone pangembangan. Wong lanang, iku kabeh kanggo aku dina iki: tuangake seneng, tulis komentar))) Kabeh babagan Pengujian Unit: metode, konsep, praktik - 11
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION