A software regression is a type of software bug where a feature that has worked before stops working. This may happen after changes are applied to the software's source code, including the addition of new features and bug fixes. They may also be introduced by changes to the environment in which the software is running, such as system upgrades, system patching or a change to daylight saving time. A software performance regression is a situation where the software still functions correctly, but performs more slowly or uses more memory or resources than before. Various types of software regressions have been identified in practice, including the following:
 Local – a change introduces a new bug in the changed module or component.
 Remote – a change in one part of the software breaks functionality in another module or component.
 Unmasked – a change unmasks an already existing bug that had no effect before the change.

Regressions are often caused by encompassed bug fixes included in software patches. One approach to avoiding this kind of problem is regression testing. A properly designed test plan aims at preventing this possibility before releasing any software. Automated testing and well-written test cases can reduce the likelihood of a regression.

Prevention and detection

Techniques have been proposed that try to prevent regressions from being introduced into software at various stages of development, as outlined below.

Prior to release

In order to avoid regressions being seen by the end-user after release, developers regularly run regression tests after changes are introduced to the software. These tests can include unit tests to catch local regressions as well as integration tests to catch remote regressions. Regression testing techniques often leverage existing test cases to minimize the effort involved in creating them. However, due to the volume of these existing tests, it is often necessary to select a representative subset, using techniques such as test-case prioritization.

For detecting performance regressions, software performance tests are run on a regular basis, to monitor the response time and resource usage metrics of the software after subsequent changes. Unlike functional regression tests, the results of performance tests are subject to variance - that is, results can differ between tests due to variance in performance measurements; as a result, a decision must be made on whether a change in performance numbers constitutes a regression, based on experience and end-user demands. Approaches such as statistical significance testing and change point detection are sometimes used to aid in this decision.

Prior to commit

Since debugging and localizing the root cause of a software regression can be expensive, there also exist some methods that try to prevent regressions from being committed into the code repository in the first place. For example, Git Hooks enable developers to run test scripts before code changes are committed or pushed to the code repository. In addition, change impact analysis has been applied to software to predict the impact of a code change on various components of the program, and to supplement test case selection and prioritization. Software linters are also often added to commit hooks to ensure consistent coding style, thereby minimizing stylistic issues that can make the software prone to regressions.

Localization

Many of the techniques used to find the root cause of non-regression software bugs can also be used to debug software regressions, including breakpoint debugging, print debugging, and program slicing. The techniques described below are often used specifically to debug software regressions.

Functional regressions

A common technique used to localize functional regressions is bisection, which takes both a buggy commit and a previously working commit as input, and tries to find the root cause by doing a binary search on the commits in between. Version control systems such as Git and Mercurial provide built-in ways to perform bisection on a given pair of commits.

Other options include directly associating the result of a regression test with code changes; setting divergence breakpoints; or using incremental data-flow analysis, which identifies test cases - including failing ones - that are relevant to a set of code changes, among others.

Performance regressions

Profiling measures the performance and resource usage of various components of a program, and is used to generate data useful in debugging performance issues. In the context of software performance regressions, developers often compare the call trees (also known as "timelines") generated by profilers for both the buggy version and the previously working version, and mechanisms exist to simplify this comparison. Web development tools typically provide developers the ability to record these performance profiles.

Logging also helps with performance regression localization, and similar to call trees, developers can compare systematically-placed performance logs of multiple versions of the same software. A tradeoff exists when adding these performance logs, as adding many logs can help developers pinpoint which portions of the software are regressing at smaller granularities, while adding only a few logs will also reduce overhead when executing the program.

Additional approaches include writing performance-aware unit tests to help with localization, and ranking subsystems based on performance counter deviations. Bisection can also be repurposed for performance regressions by considering commits that perform below (or above) a certain baseline value as buggy, and taking either the left or the right side of the commits based on the results of this comparison.

See also

 Software rot
 Software aging

References

Software bugs
소프트웨어 회귀()는 이전에는 작동했던 기능이 작동을 멈추는 소프트웨어 버그의 일종이다. 이는 새로운 기능의 추가 및 버그 수정을 포함하여 소프트웨어의 소스 코드에 변경 사항이 적용된 후에 발생할 수 있다. 또한 시스템 업그레이드, 시스템 패치 또는 일광 절약 시간제 변경과 같은 소프트웨어가 실행 중인 환경의 변경으로 인해 발생할 수도 있다. 소프트웨어 성능 회귀()는 소프트웨어가 여전히 올바르게 작동하지만 이전보다 더 느리게 수행되거나 더 많은 메모리나 자원을 사용하는 상황을 말한다. 실제로 다음과 같은 다양한 유형의 소프트웨어 회귀가 확인되었다:
 로컬 – 변경된 모듈 또는 구성 요소에 새로운 버그가 발생한다.
 원격 – 소프트웨어의 한 부분이 변경되면 다른 모듈이나 구성 요소의 기능이 손상된다.
회귀는 종종 소프트웨어 패치에 포함된 포괄적인 버그 수정으로 인해 발생한다. 이러한 종류의 문제를 방지하는 방법 중 하나는 회귀 테스트이다. 적절히 설계된 테스트 계획은 소프트웨어를 출시하기 전에 이러한 가능성을 방지하는 것을 목표로 한다. 자동화된 테스트와 잘 작성된 테스트 케이스를 통해 회귀의 가능성을 줄일 수 있다.

예방과 감지

다음과 같이 다양한 개발 단계에서 회귀가 소프트웨어에 발생하는 것을 방지하기 위한 기술이 제안되었다.

출시 이전

최종 사용자에게 릴리스 후 회귀가 나타나는 것을 방지하기 위해 개발자는 소프트웨어에 변경 사항이 적용된 후 회귀 테스트를 정기적으로 실행한다. 이러한 테스트에는 로컬 회귀를 포착하기 위한 단위 테스트와 원격 회귀를 포착하기 위한 통합 테스트가 포함된다. 회귀 테스트 기술은 종종 기존 테스트 케이스를 활용하여 만드는 데 수반되는 노력을 최소화한다. 그러나 이러한 기존 테스트의 양으로 인해 테스트 케이스 우선 순위 지정과 같은 기술을 사용하여 대표적인 하위 집합을 선택해야 하는 경우가 많다.

성능 회귀를 감지하기 위해 소프트웨어 성능 테스트를 정기적으로 실행하여 후속 변경 후 소프트웨어의 응답 시간 및 자원 사용량 메트릭을 모니터링한다. 기능 회귀 테스트와 달리 성능 테스트의 결과는 분산의 영향을 받는다. 즉, 성능 측정의 분산으로 인해 테스트 간에 결과가 다를 수 있다. 성능 수치의 변화와 최종 사용자의 요구에 따라 회귀에 해당하는지 여부를 결정해야 한다. 이 결정을 돕기 위해 통계적 가설 검정과 변경점 감지와 같은 접근 방식이 사용되기도 한다.

커밋 이전
소프트웨어 회귀의 근본 원인을 디버깅하고 국소화하는 것은 비용이 많이 들 수 있기 때문에, 애초에 회귀가 코드 저장소에 커밋되지 않도록 하는 몇 가지 방법들도 존재한다. 예를 들어 깃 훅을 사용하면 개발자가 코드 변경 사항을 커밋하거나 코드 리포지토리에 푸시하기 전에 테스트 스크립트를 실행할 수 있다. 또한, 코드 변경이 프로그램의 다양한 구성 요소에 미치는 영향을 예측하고, 테스트 케이스 선택 및 우선 순위 지정을 보완하기 위해 변경 영향 분석이 소프트웨어에 적용되었다. 또한 소프트웨어 린터는 일관된 코딩 스타일을 보장하기 위해 커밋 훅에 추가되는 경우가 많아 소프트웨어가 회귀하기 쉬운 스타일 문제를 최소화한다.

국소화

비회귀 소프트웨어 버그의 근본 원인을 찾는 데 사용되는 많은 기술들인 브레이크포인트 디버깅, 프린트 디버깅, 프로그램 슬라이싱 등은 소프트웨어 회귀 디버깅에도 사용할 수 있다. 아래에 설명된 기술은 종종 소프트웨어 회귀를 디버그하는 데에도 사용된다.

기능적 회귀

기능 회귀를 국소화하는 데 사용되는 일반적인 기술은 버그가 있는 커밋과 이전에 작업한 커밋을 모두 입력으로 사용하고 그 사이의 커밋에 대해 이진 검색을 수행하여 근본 원인을 찾으려 하는 이분법이다. 깃과 머큐리얼과 같은 버전 관리 시스템은 주어진 커밋 쌍에 대해 이분법을 수행할 수 있는 기본 제공 방법을 제공한다.

다른 옵션으로는 회귀 테스트 결과를 코드 변경과 직접 연관시키는 것, 분기 중단점을 설정하는 것, 코드 변경과 관련된 테스트 케이스(실패한 것을 포함)를 식별하는 증분 데이터 흐름 분석을 사용하는 것 등이 있다.

성능 회귀

프로파일링은 프로그램의 다양한 구성 요소의 성능과 자원 사용량을 측정하며 성능 문제를 디버깅하는 데 유용한 데이터를 생성하는 데 사용된다. 소프트웨어 성능 회귀의 맥락에서 개발자는 버그가 있는 버전과 이전에 작동하던 버전 모두에 대해 프로파일러에서 생성된 호출 트리("타임라인"이라고도 함)를 종종 비교하며 이러한 비교를 단순화하는 메커니즘이 있다. 웹 개발 도구는 일반적으로 개발자에게 이러한 성능 프로필을 기록할 수 있는 기능을 제공한다.

로깅은 또한 성능 회귀 국소화에 도움이 되며 호출 트리와 유사하게 개발자는 동일한 소프트웨어의 여러 버전에 대해 체계적으로 배치된 성능 로그를 비교할 수 있다.

이러한 성능 로그를 추가할 때 절충점이 존재하는데, 많은 로그를 추가하면 개발자가 소프트웨어의 어느 부분이 더 작은 단위에서 회귀하는지 정확히 찾아내는 데 도움이 될 수 있지만 몇 개의 로그만 추가하면 프로그램 실행 시 오버헤드가 감소할 수 있기 때문이다. 추가적인 접근 방식에는 국소화에 도움이 되는 성능 인식 단위 테스트 작성 및 성능 카운터 편차를 기준으로 하위 시스템 순위 지정 등이 있다. 또한 이분법은 성능 회귀를 위해 특정 기준 값 이하(또는 그 이상)를 수행하는 커밋을 버그가 많은 것으로 간주하고 이 비교 결과에 기초하여 커밋의 왼쪽 또는 오른쪽을 취하는 것으로 사용할 수도 있다.

같이 보기 

 소프트웨어 부패
 소프트웨어 노화

각주 

소프트웨어 버그