{{위키데이터 속성 추적}}
'''소프트웨어 회귀'''({{Lang|en|software regression}})는 이전에는 작동했던 기능이 작동을 멈추는 [[소프트웨어 버그]]의 일종이다. 이는 새로운 [[소프트웨어 기능|기능]]의 추가 및 버그 수정을 포함하여 소프트웨어의 [[소스 코드]]에 변경 사항이 적용된 후에 발생할 수 있다.<ref name=wong-issre-97>{{서적 인용|last1=Wong |first1=W. Eric |last2=Horgan |first2=J.R. |last3=London |first3=Saul |last4=Agrawal |first4=Hira |title=Proceedings of the Eighth International Symposium on Software Reliability Engineering (ISSRE 97) |date=1997 |publisher=IEEE |isbn=0-8186-8120-9 |url=https://ieeexplore.ieee.org/document/630875 |chapter=A Study of Effective Regression Testing in Practice|doi=10.1109/ISSRE.1997.630875 |s2cid=2911517 }}</ref> 또한 시스템 업그레이드, [[패치 (컴퓨팅)|시스템 패치]] 또는 [[일광 절약 시간제]] 변경과 같은 소프트웨어가 실행 중인 환경의 변경으로 인해 발생할 수도 있다.<ref name=ibm-locating-bugs>{{콘퍼런스 인용|last1=Yehudai|first1=Amiram |last2=Tyszberowicz|first2=Shmuel |last3=Nir|first3=Dor|title=Locating Regression Bugs|url=https://link.springer.com/chapter/10.1007/978-3-540-77966-7_18#:~:text=Abstract,patch%20causes%20the%20regression%20bug.|conference=Haifa Verification Conference|conference-url=https://www.research.ibm.com/haifa/conferences/hvc2017/previous.shtml|year=2007|doi=10.1007/978-3-540-77966-7_18 |accessdate=10 March 2018}}</ref> '''소프트웨어 성능 회귀'''({{Lang|en|software performance regression}}''')'''는 소프트웨어가 여전히 올바르게 작동하지만 이전보다 더 느리게 수행되거나 더 많은 메모리나 자원을 사용하는 상황을 말한다.<ref>{{저널 인용|last1=Shang|first1=Weiyi|last2=Hassan|first2=Ahmed E.|last3=Nasser|first3=Mohamed|last4=Flora|first4=Parminder|date=11 December 2014|title=Automated Detection of Performance Regressions Using Regression Models on Clustered Performance Counters|url=https://sail.cs.queensu.ca/Downloads/ICPE2015_AutomatedDetectionofPerformanceRegressionsUsingRegressionModelsOnClusteredPerformanceCounters.pdf#page=1|access-date=2022-04-10|archive-date=2021-01-13|archive-url=https://web.archive.org/web/20210113231136/https://sail.cs.queensu.ca/Downloads/ICPE2015_AutomatedDetectionofPerformanceRegressionsUsingRegressionModelsOnClusteredPerformanceCounters.pdf#page=1|url-status=}}</ref> 실제로 다음과 같은 다양한 유형의 소프트웨어 회귀가 확인되었다:<ref>{{서적 인용|last1=Henry |first1=Jean-Jacques Pierre |title=The Testing Network: An Integral Approach to Test Activities in Large Software Projects |date=2008 |publisher=Springer Science & Business Media |isbn=978-3540785040 |page=74}}</ref>
* 로컬 – 변경된 모듈 또는 구성 요소에 새로운 버그가 발생한다.
* 원격 – 소프트웨어의 한 부분이 변경되면 다른 모듈이나 구성 요소의 기능이 손상된다.
회귀는 종종 [[소프트웨어 패치]]에 포함된 [[핫픽스|포괄적인 버그 수정]]으로 인해 발생한다. 이러한 종류의 문제를 방지하는 방법 중 하나는 [[회귀 테스트]]이다. 적절히 설계된 [[테스트 계획]]은 소프트웨어를 출시하기 전에 이러한 가능성을 방지하는 것을 목표로 한다.<ref>{{서적 인용|last=Richardson |first=Jared |author2=Gwaltney, William Jr |title=Ship It! A Practical Guide to Successful Software Projects |url=https://archive.org/details/shipitpracticalg0000rich/page/32 |year=2006 |publisher=The Pragmatic Bookshelf |location=Raleigh, NC |pages=[https://archive.org/details/shipitpracticalg0000rich/page/32 32, 193] |isbn=978-0-9745140-4-8 }}</ref> [[테스트 자동화|자동화된 테스트]]와 잘 작성된 [[테스트 케이스]]를 통해 회귀의 가능성을 줄일 수 있다.

==예방과 감지==

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

===출시 이전===

{{본문|회귀 테스트}}

[[최종 사용자]]에게 릴리스 후 회귀가 나타나는 것을 방지하기 위해 개발자는 소프트웨어에 변경 사항이 적용된 후 [[회귀 테스트]]를 정기적으로 실행한다. 이러한 테스트에는 로컬 회귀를 포착하기 위한 [[단위 테스트]]와 원격 회귀를 포착하기 위한 [[통합 테스트]]가 포함된다.<ref>{{서적 인용|last1=Leung |first1=Hareton K.N. |last2=White |first2=Lee |title=Proceedings of the International Conference on Software Maintenance |date=November 1990 |publisher=IEEE |location=San Diego, CA, USA |isbn=0-8186-2091-9 |url=https://ieeexplore.ieee.org/document/131377 |chapter=A study of integration testing and software regression at the integration level|doi=10.1109/ICSM.1990.131377 |s2cid=62583582 }}</ref> 회귀 테스트 기술은 종종 기존 테스트 케이스를 활용하여 만드는 데 수반되는 노력을 최소화한다.<ref>{{저널 인용|last1=Rothermel |first1=Gregg |last2=Harrold |first2=Mary Jean |last3=Dedhia |first3=Jeinay |title=Regression test selection for C++ software |journal=Software Testing, Verification and Reliability |date=2000 |volume=10 |issue=2 |pages=77–109 |doi=10.1002/1099-1689(200006)10:2<77::AID-STVR197>3.0.CO;2-E |url=https://onlinelibrary.wiley.com/doi/abs/10.1002/1099-1689(200006)10:2%3C77::AID-STVR197%3E3.0.CO;2-E |language=en |issn=1099-1689}}</ref> 그러나 이러한 기존 테스트의 양으로 인해 [[회귀 테스트|테스트 케이스 우선 순위 지정]]과 같은 기술을 사용하여 대표적인 하위 집합을 선택해야 하는 경우가 많다.

성능 회귀를 감지하기 위해 [[소프트웨어 성능 테스트]]를 정기적으로 실행하여 후속 변경 후 소프트웨어의 응답 시간 및 자원 사용량 메트릭을 모니터링한다.<ref>{{저널 인용|last1=Weyuker |first1=E.J. |last2=Vokolos |first2=F.I. |title=Experience with performance testing of software systems: issues, an approach, and case study |journal=IEEE Transactions on Software Engineering |date=December 2000 |volume=26 |issue=12 |pages=1147–1156 |doi=10.1109/32.888628 |url=https://ieeexplore.ieee.org/document/888628 |issn=1939-3520}}</ref> 기능 회귀 테스트와 달리 성능 테스트의 결과는 [[분산]]의 영향을 받는다. 즉, 성능 측정의 분산으로 인해 테스트 간에 결과가 다를 수 있다. 성능 수치의 변화와 최종 사용자의 요구에 따라 회귀에 해당하는지 여부를 결정해야 한다. 이 결정을 돕기 위해 [[통계적 가설 검정]]과 [[변경점 감지]]와 같은 접근 방식이 사용되기도 한다.<ref>{{서적 인용|last1=Daly |first1=David |last2=Brown |first2=William |last3=Ingo |first3=Henrik |last4=O'Leary |first4=Jim |last5=Bradford |first5=David |title=Proceedings of the International Conference on Performance Engineering |date=20 April 2020 |publisher=Association for Computing Machinery |isbn=978-1-4503-6991-6 |pages=67–75 |url=https://dl.acm.org/doi/abs/10.1145/3358960.3375791 |chapter=The Use of Change Point Detection to Identify Software Performance Regressions in a Continuous Integration System|doi=10.1145/3358960.3375791 |s2cid=211677818 }}</ref>

===커밋 이전===
소프트웨어 회귀의 근본 원인을 [[디버깅]]하고 국소화하는 것은 비용이 많이 들 수 있기 때문에,<ref>{{서적 인용|last1=Nistor |first1=Adrian |last2=Jiang |first2=Tian |last3=Tan |first3=Lin |title=Proceedings of the Working Conference on Mining Software Repositories (MSR) |date=May 2013 |pages=237–246 |url=https://ieeexplore.ieee.org/document/6624035 |chapter=Discovering, reporting, and fixing performance bugs|doi=10.1109/MSR.2013.6624035 |isbn=978-1-4673-2936-1 |s2cid=12773088 }}</ref><ref>{{저널 인용|last1=Agarwal |first1=Pragya |last2=Agrawal |first2=Arun Prakash |title=Fault-localization techniques for software systems: a literature review |journal=ACM SIGSOFT Software Engineering Notes |date=17 September 2014 |volume=39 |issue=5 |pages=1–8 |doi=10.1145/2659118.2659125 |s2cid=12101263 |url=https://dl.acm.org/doi/abs/10.1145/2659118.2659125 |issn=0163-5948}}</ref> 애초에 회귀가 [[코드 저장소]]에 커밋되지 않도록 하는 몇 가지 방법들도 존재한다. 예를 들어 [[깃 (소프트웨어)|깃]] 훅을 사용하면 개발자가 코드 변경 사항을 커밋하거나 코드 리포지토리에 푸시하기 전에 테스트 스크립트를 실행할 수 있다.<ref>{{웹 인용|title=Git - Git Hooks |url=https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks |website=git-scm.com |access-date=7 November 2021}}</ref> 또한, 코드 변경이 프로그램의 다양한 구성 요소에 미치는 영향을 예측하고, 테스트 케이스 선택 및 우선 순위 지정을 보완하기 위해 [[변경 영향 분석]]이 소프트웨어에 적용되었다.<ref>{{저널 인용|last1=Orso |first1=Alessandro |last2=Apiwattanapong |first2=Taweesup |last3=Harrold |first3=Mary Jean |title=Leveraging field data for impact analysis and regression testing |journal=ACM SIGSOFT Software Engineering Notes |date=1 September 2003 |volume=28 |issue=5 |pages=128–137 |doi=10.1145/949952.940089 |url=https://dl.acm.org/doi/abs/10.1145/949952.940089 |issn=0163-5948}}</ref><ref>{{서적 인용|last1=Qu |first1=Xiao |last2=Acharya |first2=Mithun |last3=Robinson |first3=Brian |title=Proceedings of the International Conference on Software Maintenance |date=September 2012 |pages=129–138 |url=https://ieeexplore.ieee.org/document/6405263 |chapter=Configuration selection using code change impact analysis for regression testing|doi=10.1109/ICSM.2012.6405263 |isbn=978-1-4673-2312-3 |s2cid=14928793 }}</ref> 또한 [[소프트웨어 린터]]는 일관된 코딩 스타일을 보장하기 위해 커밋 훅에 추가되는 경우가 많아 소프트웨어가 회귀하기 쉬운 스타일 문제를 최소화한다.<ref>{{서적 인용|last1=Tómasdóttir |first1=Kristín Fjóla |last2=Aniche |first2=Mauricio |last3=van Deursen |first3=Arie |title=Proceedings of the International Conference on Automated Software Engineering |date=October 2017 |pages=578–589 |url=https://ieeexplore.ieee.org/document/8115668 |chapter=Why and how JavaScript developers use linters|doi=10.1109/ASE.2017.8115668 |isbn=978-1-5386-2684-9 }}</ref>

==국소화==

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

===기능적 회귀===

기능 회귀를 국소화하는 데 사용되는 일반적인 기술은 버그가 있는 커밋과 이전에 작업한 커밋을 모두 입력으로 사용하고 그 사이의 커밋에 대해 이진 검색을 수행하여 근본 원인을 찾으려 하는 [[이분법 (소프트웨어 공학)|이분법]]이다.<ref>{{서적 인용|last1=Gross |first1=Thomas |title=Proceedings of the International Workshop on Automatic Debugging |date=10 September 1997 |publisher=Linkøping University Electronic Press |pages=185–191 |url=https://ep.liu.se/en/conference-article.aspx?series=ecp&issue=1&Article_No=15 |language=en |chapter=Bisection Debugging}}</ref> 깃과 [[머큐리얼]]과 같은 [[버전 관리]] 시스템은 주어진 커밋 쌍에 대해 이분법을 수행할 수 있는 기본 제공 방법을 제공한다.<ref>{{웹 인용|title=Git - git-bisect Documentation |url=https://git-scm.com/docs/git-bisect |website=git-scm.com |access-date=7 November 2021}}</ref><ref>{{웹 인용|title=hg - bisect |url=https://www.selenic.com/mercurial/hg.1.html |website=www.selenic.com |publisher=Mercurial |access-date=7 November 2021}}</ref>

다른 옵션으로는 회귀 테스트 결과를 코드 변경과 직접 연관시키는 것,<ref>{{웹 인용|title=Reading 11: Debugging |url=https://web.mit.edu/6.005/www/fa15/classes/11-debugging/ |website=web.mit.edu |publisher=MIT}}</ref> 분기 중단점을 설정하는 것,<ref>{{서적 인용|last1=Buhse |first1=Ben |last2=Wei |first2=Thomas |last3=Zang |first3=Zhiqiang |last4=Milicevic |first4=Aleksandar |last5=Gligoric |first5=Milos |title=Proceedings of the International Conference on Software Engineering: Companion Proceedings (ICSE-Companion) |date=May 2019 |pages=15–18 |url=https://ieeexplore.ieee.org/document/8802682 |chapter=VeDebug: Regression Debugging Tool for Java|doi=10.1109/ICSE-Companion.2019.00027 |isbn=978-1-7281-1764-5 |s2cid=174799830 }}</ref> 코드 변경과 관련된 테스트 케이스(실패한 것을 포함)를 식별하는 증분 [[데이터 흐름 분석]]을 사용하는 것<ref>{{서적 인용|last1=Taha |first1=A.-B. |last2=Thebaut |first2=S.M. |last3=Liu |first3=S.-S. |title=Proceedings of the Annual International Computer Software & Applications Conference |date=September 1989 |publisher=IEEE |pages=527–534 |url=https://ieeexplore.ieee.org/document/65142 |chapter=An approach to software fault localization and revalidation based on incremental data flow analysis|doi=10.1109/CMPSAC.1989.65142 |isbn=0-8186-1964-3 |s2cid=41978046 }}</ref> 등이 있다.

===성능 회귀===

[[프로파일링 (컴퓨터 프로그래밍)|프로파일링]]은 프로그램의 다양한 구성 요소의 성능과 자원 사용량을 측정하며 성능 문제를 디버깅하는 데 유용한 데이터를 생성하는 데 사용된다. 소프트웨어 성능 회귀의 맥락에서 개발자는 버그가 있는 버전과 이전에 작동하던 버전 모두에 대해 프로파일러에서 생성된 [[호출 스택|호출 트리]]("타임라인"이라고도 함)를 종종 비교하며 이러한 비교를 단순화하는 메커니즘이 있다.<ref>{{저널 인용|last1=Ocariza |first1=Frolin S. |last2=Zhao |first2=Boyang |title=Localizing software performance regressions in web applications by comparing execution timelines |journal=Software Testing, Verification and Reliability |date=2021 |volume=31 |issue=5 |pages=e1750 |doi=10.1002/stvr.1750 |s2cid=225416138 |url=https://onlinelibrary.wiley.com/doi/abs/10.1002/stvr.1750 |language=en |issn=1099-1689}}</ref> [[웹 개발 도구]]는 일반적으로 개발자에게 이러한 성능 프로필을 기록할 수 있는 기능을 제공한다.<ref>{{웹 인용|title=Analyze runtime performance |url=https://developer.chrome.com/docs/devtools/evaluate-performance/ |website=Chrome Developers |publisher=Google |access-date=7 November 2021 |language=en}}</ref><ref>{{웹 인용|title=Performance analysis reference - Microsoft Edge Development |url=https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/evaluate-performance/reference |website=docs.microsoft.com |publisher=Microsoft |access-date=7 November 2021 |language=en-us}}</ref>

로깅은 또한 성능 회귀 국소화에 도움이 되며 호출 트리와 유사하게 개발자는 동일한 소프트웨어의 여러 버전에 대해 체계적으로 배치된 성능 로그를 비교할 수 있다.<ref>{{서적 인용|last1=Yao |first1=Kundi |last2=B. de Pádua |first2=Guilherme |last3=Shang |first3=Weiyi |last4=Sporea |first4=Steve |last5=Toma |first5=Andrei |last6=Sajedi |first6=Sarah |title=Proceedings of the International Conference on Performance Engineering |date=30 March 2018 |publisher=Association for Computing Machinery |isbn=978-1-4503-5095-2 |pages=127–138 |url=https://dl.acm.org/doi/abs/10.1145/3184407.3184416 |chapter=Log4Perf: Suggesting Logging Locations for Web-based Systems' Performance Monitoring|doi=10.1145/3184407.3184416 |s2cid=4557038 }}</ref>

이러한 성능 로그를 추가할 때 절충점이 존재하는데, 많은 로그를 추가하면 개발자가 소프트웨어의 어느 부분이 더 작은 단위에서 회귀하는지 정확히 찾아내는 데 도움이 될 수 있지만 몇 개의 로그만 추가하면 프로그램 실행 시 오버헤드가 감소할 수 있기 때문이다.<ref>{{저널 인용|title=A Qualitative Study of the Benefits and Costs of Logging from Developers' Perspectives |journal=IEEE Transactions on Software Engineering |date=30 January 2020 |doi=10.1109/TSE.2020.2970422 |url=https://ieeexplore.ieee.org/document/8976297|last1=Li |first1=Heng |last2=Shang |first2=Weiyi |last3=Adams |first3=Bram |last4=Sayagh |first4=Mohammed |last5=Hassan |first5=Ahmed E. |volume=47 |issue=12 |pages=2858–2873 |s2cid=213679706 }}</ref> 추가적인 접근 방식에는 국소화에 도움이 되는 성능 인식 단위 테스트 작성<ref>{{서적 인용|last1=Heger |first1=Christoph |last2=Happe |first2=Jens |last3=Farahbod |first3=Roozbeh |title=Proceedings of the International Conference on Performance Engineering |date=21 April 2013 |publisher=Association for Computing Machinery |isbn=978-1-4503-1636-1 |pages=27–38 |url=https://dl.acm.org/doi/abs/10.1145/2479871.2479879 |chapter=Automated root cause isolation of performance regressions during software development|doi=10.1145/2479871.2479879 |s2cid=2593603 }}</ref> 및 성능 카운터 편차를 기준으로 하위 시스템 순위 지정 등이 있다.<ref>{{서적 인용|last1=Malik |first1=Haroon |last2=Adams |first2=Bram |last3=Hassan |first3=Ahmed E. |title=Proceedings of the International Symposium on Software Reliability Engineering |date=November 2010 |pages=201–210 |url=https://ieeexplore.ieee.org/document/5635038 |chapter=Pinpointing the Subsystems Responsible for the Performance Deviations in a Load Test|doi=10.1109/ISSRE.2010.43 |isbn=978-1-4244-9056-1 |s2cid=17306870 }}</ref> 또한 이분법은 성능 회귀를 위해 특정 기준 값 이하(또는 그 이상)를 수행하는 커밋을 버그가 많은 것으로 간주하고 이 비교 결과에 기초하여 커밋의 왼쪽 또는 오른쪽을 취하는 것으로 사용할 수도 있다.

== 같이 보기 ==
* [[소프트웨어 부패]]
* [[소프트웨어 노화]]

== 각주 ==
{{각주}}

[[분류:소프트웨어 버그]]