Regressionstestning är processen att ompröva applikationen efter ändringar för att upptäcka defekter i tidigare fungerande funktionalitet. Varje kodändring — ny funktionalitet, buggfix eller refaktorering — kan oavsiktligt bryta applikationens befintliga funktioner. Regressionstester automatiserar verifieringen att den gamla funktionaliteten förblir fungerande. Enligt IBM, 2023 täcker regressionstestning 30 till 70 % av alla utförda tester i kommersiella produktteam, vilket understryker dess roll som den främsta barriären mot produktionsincidenter.
Huvudpunkter
Regressionstestning är en typ av testning som syftar till att bekräfta att kodändringar inte har påverkat befintlig funktionalitet. Termen „regression” betyder återgång till ett sämre tillstånd — när en funktion som fungerade i den tidigare versionen slutar fungera i den nya. Regressionstester utförs upprepade gånger i varje utvecklingscykel, vilket skiljer dem från tester av ny funktionalitet som skrivs en gång.
Behovet av regressionstestning härrör från effekten av kaskadförändringar: att åtgärda en bugg i en modul kan lösa problemet men bryta angränsande funktionalitet som var beroende av den. Till exempel kan en ändring av en SQL-fråga i användararkivet påskynda inloggningen men bryta dataexporten som använde samma fråga. Ett regressionstest för dataexport kommer att upptäcka detta brott före releasen.
Enligt CISQ 2023-rapporten är kostnaden för att åtgärda en regressionstestdefekt som upptäckts i produktionen 15 gånger högre än i fasen av automatiserad regressionstestning. Företag som investerar i automatiserad regressionstestning minskar andelen regressionstestdefekter i releaser från 25 % till 5 % inom ett år efter implementering, enligt Capgemini World Quality Report.
Det finns flera angreppssätt för regressionstestning, som skiljer sig åt i omfattning och urvalskriterier för tester. Valet av angreppssätt beror på projektets storlek, ändringsfrekvens och tillgänglig tid i CI-pipelinen. Nedan presenteras huvudtyperna av regressionstestning med deras egenskaper.
Fullständig regressionstestning utför alla automatiserade tester i projektet utan undantag. Detta angreppssätt ger maximal säkerhet men kräver betydande beräkningsresurser och tid. Fullständig körning utförs före stora releaser — en gång var 2–4:e vecka. För en applikation med 5000 tester tar en fullständig körning 2 till 6 timmar beroende på infrastruktur.
Selektivt angreppssätt kör endast tester som är kopplade till ändrade moduler. För att bestämma sambandet används beroendeanalys på kodnivå: om klassen UserRepository har ändrats körs tester som är direkt eller transitivt beroende av UserRepository. Verktygen Jacoco, Android Test Coverage och Xcode Code Coverage tillhandahåller täckningskartor för exakt urval. Selektiv körning utförs vid varje pull request och tar 5–15 minuter.
Riskbaserad regression rangordnar tester efter funktionalitetens kritikalitet och sannolikhet för fel. Kritiska funktioner — betalning, auktorisering, synkronisering — testas vid varje kodändring. Hjälpfunktioner — skärmen „Om appen”, animationer — testas endast före release. Rangordningen ses över kvartalsvis baserat på data om produktionsincidenter.
Begreppen regressionstestning och omtestning förväxlas ofta, även om de är olika processer. Omtestning är att åter köra ett specifikt test som tidigare misslyckades, efter att defekten har åtgärdats. Syftet med omtestning är att bekräfta att åtgärden fungerar: buggen reproduceras inte längre. Omtestning utförs en gång, omedelbart efter åtgärd och bekräftelse av åtgärden från utvecklaren.
Regressionstestning är att köra tester på befintlig funktionalitet som INTE har ändrats. Syftet är att bekräfta att åtgärdandet av en defekt inte har skapat en ny defekt på annan plats. Regressionstester körs upprepade gånger i varje utvecklingscykel, oavsett vilka specifika buggar som har åtgärdats. Huvudskillnaden: omtestning kontrollerar själva åtgärden, regression kontrollerar konsekvenserna av åtgärden.
I CI/CD-pipelinen utförs båda processerna sekventiellt. Efter sammanslagning av pull request körs omtestning av den specifika buggen, följt av fullständig eller selektiv regressionstestning. Enligt SmartBear (2022) minskar separeringen av dessa processer diagnostiseringstiden för misslyckade CI-körningar med 30 %, eftersom teamet omedelbart ser vilken del av defekterna som är relaterade till regression och vilken som är relaterad till icke-fungerande åtgärder.
Automatisering av regressionstestning är en kritisk framgångsfaktor för moderna mobilprojekt. Manuell regressionstestning är inte skalbar: med en uppsättning på 200 tester kräver en körning 2–3 arbetsdagar för en QA-ingenjör, vilket gör dagliga körningar omöjliga. Automatiserade regressionstester utförs på 10–60 minuter utan mänsklig inblandning, vilket gör att de kan köras vid varje commit eller pull request.
För att hålla regressionstestningsuppsättningen aktuell används testanalys: verktyg som Allure, ReportPortal och Xray spårar godkännandeprocent, varaktighet och stabilitet för varje test. Tester vars stabilitet sjunker under 90 % (går ofta sönder på grund av ändringar i krav) markeras som legacy och skickas för översyn till ägaren.
Låt oss titta på konfigurationen av ett automatiserat regressionstest på Android med hjälp av biblioteket JUnit 5 och Espresso. Exemplet demonstrerar selektiv regression — testet kontrollerar att profilsidan inte har gått sönder efter refaktorering av användararkivet. För iOS används XCTest med liknande logik — ett upprepat test av det viktigaste scenariot.
Testet använder MockWebServer för serveremulering och kontrollerar hela vägen: laddning av användardata, visning på profilsidan och felhantering när servern inte är tillgänglig. Sådana tester ingår i regressionstestningsuppsättningen och körs vid varje ändring i module-profile.
@RunWith(AndroidJUnit4::class)
class ProfileRegressionTest {
@get:Rule
val composeRule = createComposeRule()
@Test
fun profileScreen_rendersCorrectly() {
val user = User(id = 1, name = "Alice", email = "alice@test.com")
composeRule.setContent {
ProfileScreen(user)
}
composeRule.onNodeWithText("Alice").assertIsDisplayed()
composeRule.onNodeWithText("alice@test.com").assertIsDisplayed()
}
@Test
fun profileScreen_handlesNetworkError() {
setNetworkError()
composeRule.onNodeWithText("Laddningsfel").assertIsDisplayed()
}
}
För iOS använder regressionstestet XCTestExpectation för asynkron kontroll av UI-uppdatering efter mottagning av data från API:et. Testet emulerar ett nätverkssvar och kontrollerar att UI-elementen har uppdaterats korrekt.
class ProfileRegressionTests: XCTestCase {
func testProfileScreen_rendersCorrectly() {
let viewModel = ProfileViewModel(userId: 1)
let view = ProfileView(viewModel: viewModel)
viewModel.loadProfile()
let expectation = expectation(description: "profile loaded")
viewModel.onProfileLoaded = {
XCTAssertEqual(viewModel.userName, "Alice")
XCTAssertEqual(viewModel.userEmail, "alice@test.com")
expectation.fulfill()
}
waitForExpectations(timeout: 3.0)
}
}
Att bygga en effektiv regressionstestningsuppsättning är en iterativ process baserad på data om defekter och kodändringar. Den primära strategin är att inkludera alla befintliga tester i regressionstestningsuppsättningen och köra fullständig körning före varje release. I takt med att testbasen växer (över 2000 tester) blir den fullständiga körningen för lång och ett selektivt angreppssätt krävs.
Den andra fasen — införande av verktyg för beroendeanalys: Jacoco för Android, Xcode Test Plan för iOS. Dessa verktyg bygger en „test — klass — metod”-karta och gör det möjligt att bestämma vilka tester som påverkas av en specifik ändring. Selektiv körning baserad på täckningsanalys minskar exekveringstiden med 60–80 % samtidigt som 95 % effektivitet i regressionstestdetektering bibehålls, enligt Spotify Engineering (2022).
Den tredje fasen — kontinuerlig övervakning och optimering. Tester som inte har misslyckats på 6 månader flyttas till en lågprioriterad uppsättning. Tester som misslyckas oftare än en gång i månaden är kandidater för översyn: antingen fångar de verkliga problem (kräver åtgärd) eller är de för ömtåliga (kräver stabilisering). Kvartalsvis revidering av regressionstestningsuppsättningen är standardpraxis för att bibehålla dess effektivitet och exekveringshastighet.
Vanliga frågor
Selektiv regressionstestning — vid varje pull request. Fullständig regressionstestning — före varje release och veckovis (nightly build). Huvudregeln: ju oftare körning, desto snabbare upptäcks regressioner och desto lägre är kostnaden för att åtgärda dem. För kritiska projekt är fullständig regressionstestning möjlig vid varje sammanslagning.
Alla enhetstester (grundläggande regression), integrationstester på nyckelkomponenter och UI-tester på kritiska användarscenarier. Inkludera inte tester av experimentell funktionalitet, tester med flakiness över 10 % och tester som kräver manuell miljö.
Ta bort tester för borttagen funktionalitet, uppdatera tester när krav ändras, genomför kvartalsvis revision av uppsättningen. CI-analys — Allure, ReportPortal — hjälper till att identifiera tester som har förlorat sin relevans: om ett test inte har ändrats och inte misslyckats på 3 månader är det en kandidat för borttagning från den dagliga körningen.
Använd parallell testkörning på flera enheter, implementera selektiv regressionstestning baserad på täckningsanalys av ändrad kod, stäng av visuella skärmbilder för irrelevanta skärmar. Måltid för selektiv körning — 5–10 minuter, för fullständig körning — högst 2 timmar.
Nej, regressionstestning inkluderar även manuella kontroller: utforskande testning efter release, UX-regression och tillgänglighetskontroll efter gränssnittsändring. Automatisering täcker 70–80 % av regressionstestkontrollerna; de återstående 20–30 % är manuella tester som fokuserar på scenarier som inte kan eller är för dyra att automatisera.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också