Microsoft Visual Studio 2005 Team System 웹 테스트 소개

Mark Michaelis

2005년 9월

요약:
Microsoft Visual Studio 2005 Team System
Web development

요약: 이 문서에서는 Microsoft Visual Studio 2005 Team System의 웹 테스트 기능을 소개하고 웹 테스트 사례를 작성 및 사용자 지정하는 방법에 대해 설명합니다.

목차

소개
개인 웹 사이트 만들기
테스트 프로젝트 만들기
웹 테스트 사례 실행
요청 규칙
데이터 소스에 테스트 데이터 바인딩
웹 테스트 코드 생성
VSTS 웹 테스트 확장
브라우저 사용자 인터페이스 테스트
테스트 기반 개발
결론

소개

최근에 저는 한 모임에서 웹 테스트가 불가능하다고 주장하는 개발 팀과 대화를 나눈 적이 있으며 모임에 참석한 모든 사람은 웹 테스트를 수행하는 방법에 많은 비용이 들어간다고 생각하고 있었습니다. Microsoft는 이러한 비용 문제를 이미 알고 있었기 때문에 조만간 출시될 Microsoft Visual Studio Team System에서는 웹 테스트를 위한 도구가 제공될 것입니다. 이 문서에서는 바로 이 기능에 대해 개괄적으로 살펴보려고 합니다. 먼저 이 문서에서는 코드 작성 없이 웹 테스트 사례를 설정하고 사용자 지정하는 방법을 단계별로 다룹니다. 이러한 방법은 개발자가 아닌 일반 사용자를 비롯하여 개발 프로세스에 참가하는 모든 사람이 VSTS 웹 테스트를 사용할 수 있다는 것을 보여 줍니다. 또한 웹 테스트 사례를 쉽게 코딩할 수 있는데 코딩된 웹 테스트를 사용하거나 기본 제공된 웹 테스트 지원을 확장하는 방법에 대해서도 설명합니다.

이 문서를 시작하기 전에 VSTS 기능이 사용자 인터페이스 테스트용으로 설계되지 않았다는 점에 주의해야 합니다. 이 기능은 웹 페이지의 JavaScript를 실행하거나 여러 브라우저 내에서 페이지 모양을 검증하지 않습니다. 대신에 이 테스트 방식은 회선을 따라 전송되는 HTTP 데이터를 검사하고 이 데이터의 유효성을 검사하기 위한 다양한 규칙을 제공합니다.

또한 웹 사이트가 존재하는 경우에만 VSTS 웹 테스트가 웹 사이트에 대한 작업 기록을 지원하기 때문에 웹 사이트와 테스트 프로젝트 자체를 먼저 설정해야 합니다. 웹 사이트를 만든 후에는 웹 사이트에 대한 자동화된 테스트를 추가합니다. 정확하게 말해서 이러한 과정이 테스트 기반 개발은 아니지만 기록 기능은 아주 편리하기 때문에 검토할 만한 가치가 충분히 있을 것입니다.

개인 웹 사이트 만들기

이 문서에서 테스트하려는 사이트는 개인 웹 사이트이며 Microsoft Visual Studio 2005에서 제공되는 마법사로 작성된 사이트 중 하나입니다. 이 사이트를 만드는 단계는 다음과 같습니다.

  1. 파일(File) 메뉴를 클릭하고 새 웹 사이트(New Web Site)를 클릭합니다. Visual Studio 2005에서 새 웹 사이트 프로젝트는 다른 새 프로젝트 옵션과 별도의 대화 상자에 있습니다.
  2. 개인 웹 사이트 시작 키트(Personal Web Site Starter Kit)를 선택하고 프로그래밍 언어를 선택합니다. 이 문서에서는 Microsoft C#를 사용합니다.
큰 그림으로 보려면 이미지를 클릭

그림 1. 새 웹 사이트 만들기(큰 그림으로 보려면 이미지를 클릭)

사이트가 작성된 후에는 새 계정을 만듭니다. 모든 것이 제대로 작동하는지 확인하기 위해 새 계정을 수동으로 만듭니다. 나중에는 새 계정을 사용하여 사이트에 로그인하는 자동화된 테스트가 제공될 것입니다.

  1. 웹 사이트(Website)를 클릭한 다음 ASP.NET 구성(ASP.NET Configuration)을 클릭하여 웹 사이트 관리 도구를 엽니다.
  2. 보안(Security) 링크를 클릭한 다음 사용자 만들기(Create User) 링크를 클릭합니다.
  3. 사용자 만들기(Create User) 단추를 클릭하기 전에 테스트 사용자의 정보를 입력하고 역할에 맞는 관리자(Administrators)를 선택합니다. 전자 메일 주소의 형식이 정확해야 하며 암호의 길이는 적어도 하나 이상의 영숫자가 아닌 문자를 포함하여 7자여야 합니다.
  4. 계정을 만든 후에 ASP.NET 구성 웹 사이트를 종료합니다.

Visual Studio에서 웹 사이트를 시작하고 새 계정으로 로그인하여 모든 것이 제대로 작동하는지 확인할 수 있습니다.

기본적으로 사이트를 호스팅하기 위해 Microsoft IIS(Internet Information Server)가 사용되지 않습니다. 대신에 그림 2의 시스템 트레이 아이콘에 나온 것처럼 Visual Studio 2005는 Microsoft ASP.NET Development Server를 시작합니다.

그림 2. ASP.NET Development Server 시스템 트레이 아이콘

ASP.NET Development Server는 열려 있는 포트를 임의로 선택하고 웹 프로젝트의 이름에 해당하는 가상 경로를 사용하여 해당 포트에서 사이트 호스팅을 시작합니다. 그러나 Visual Studio의 이전 시작과 다음 시작 사이에 포트가 변경될 수 있으며 이 경우 원래 포트에 대한 기록된 모든 테스트가 더 이상 작동하지 않습니다. 다음과 같이 포트를 특정 값으로 고정시켜서 이 문제를 방지할 수 있습니다.

  1. Visual Studio에서 F4 키를 눌러 웹 프로젝트의 속성(Properties) 창으로 이동한 다음 포트 번호를 확인합니다. 이 창은 프로젝트의 속성 페이지(Property Pages) 대화 상자가 아니라 Visual Studio 2005 내에 있는 도킹된 창입니다. 동적 포트 사용(Use Dynamic Ports) 값은 기본적으로 True로 되어 있습니다.
  2. Visual Studio에서 다른 포트 번호를 선택하지 않게 하려면 동적 포트 사용(Use Dynamic Ports) 옵션을 False로 변경합니다.

웹 사이트를 시작하는 또 다른 방법은 WebDev.WebServer.exe를 직접 실행하는 것입니다. 이 방법을 사용하면 사이트를 호스팅하는 포트 번호를 지정할 수도 있습니다. 명령줄은 다음과 같습니다.

WebDeb.WebServer /port:<port number> /path:<physical path>
[/vpath:<virtual path>]

예를 들어, 다음을 사용하여 개인 웹 사이트를 시작할 수 있습니다.

start /B webdev.webserver.exe /port:4955
/path:"c:\documents and settings\MMichael\Local
Settings\Temp\HelloWorldWebSite" /vpath:/HelloWorldWebSite

Start는 명령이 종료하기를 기다리는 대신에 반환되도록 합니다.

포트가 지정되지 않은 경우 기본적으로 80이 사용되지만 IIS가 실행되면서 동일한 포트를 사용하는 중이면 오류가 발생합니다. 특정 포트를 허용하는 것 외에도 Visual Studio 2005를 시작할 필요 없이 빌드/테스트 스크립트의 일부로 호출할 수 있다는 점에서 WebDev.WebServer.exe는 중요합니다.

사이트가 작동하고 있다는 것을 확인하면 사이트의 기본 페이지 URL(포트 및 가상 디렉터리 포함)을 기록하고 브라우저 창을 닫습니다. 조금 있다가 웹 테스트 사례를 기록할 때 이 URL을 사용합니다. 단, 웹 테스트를 실행하려면 테스트 프로젝트가 필요합니다.

테스트 프로젝트 만들기

VSTS 단위 테스트 프로젝트에서와 마찬가지로 테스트 프로젝트를 만듭니다. 아래 단계는 이 프로세스를 개괄적으로 보여 줍니다. 테스트를 성공적으로 기록하려면 웹 사이트가 실행 중에 있어야 합니다.

  1. 솔루션을 마우스 오른쪽 단추로 클릭하고 프로젝트 추가(Add Project)를 클릭합니다.
  2. 프로그래밍 언어를 선택하고 테스트 노드를 선택합니다.
  3. 프로젝트의 이름을 HelloWorldWebSite.Test로 지정합니다.
큰 그림으로 보려면 이미지를 클릭

그림 3. 테스트 프로젝트 만들기(큰 그림으로 보려면 이미지를 클릭)

시작 웹 사이트를 이미 만들었기 때문에 사이트에 대한 작업을 기록할 수 있습니다.

자신을 웹 테스트 프로젝트로 정의하는 프로젝트를 작성하는 것과 관련하여 특별한 사항은 없습니다. 대신에 프로젝트에 추가된 테스트 파일은 단위 테스트, 로드 테스트, 수동 테스트, 일반 테스트 등의 다른 테스트 파일 형식이 아니라 특별한 웹 테스트 파일입니다. 따라서 다음 단계는 웹 테스트 사례를 추가하는 것입니다. 테스트 프로젝트에 추가되는 다른 형식의 테스트 파일은 사용하지 않을 것이므로 이러한 파일은 삭제할 수 있습니다.

  1. 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가(Add)를 클릭한 다음 웹 테스트(Web Test)를 클릭합니다. 특수한 웹 테스트 레코더 탐색 창이 있는 브라우저가 열립니다.

    그림 4. 웹 테스트 사례 기록

  2. ASP.NET Development Server에서 선택한 포트를 비롯한 개인 웹 사이트의 URL을 주소 표시줄에 입력합니다. 입력된 다른 URL과 마찬가지로 이 위치로 이동했을 때 웹 테스트 레코더 탐색 창에 해당 작업이 기록됩니다.
  3. 앞에서 추가한 사용자 이름과 암호를 입력합니다. 로그인(Login) 단추를 누르면 양식 게시 매개 변수와 함께 다른 항목이 기록됩니다. 이렇게 하여 테스트가 실행되면 동일한 데이터가 자동으로 전송됩니다. 심지어 단추를 클릭한 위치에 해당하는 X 및 Y 좌표가 요청의 일부로 전송되기 때문에 이러한 데이터도 테스트로 일부로 저장됩니다.
  4. 사이트에서 로그아웃한 다음 유효한 자격 증명으로 다시 로그인을 시도하여 추가 단계를 테스트에 추가합니다.
  5. 원하는 테스트가 기록된 후에는 브라우저 창을 닫고 테스트를 저장합니다.

이제 프로젝트에는 기록된 각 요청과 함께 웹 테스트 사례 파일이 자동으로 포함됩니다.

그림 5. 기록된 웹 테스트 사례 보기

WebTest 트리 내에 있는 노드 중 하나를 선택하면 속성(Properties) 창의 데이터를 수정할 수 있습니다.

또한 트랜잭션을 사용하여 요청을 그룹화할 수 있습니다. 상태가 단위로 커밋되거나 커밋되지 않는 프로그래밍 개념을 “트랜잭션”이라는 용어와 혼동하지 않도록 주의합니다. 웹 테스트 사례에서 트랜잭션은 단지 작업을 그룹으로 캡술화하는 역할만 수행하며 이 그룹을 나중에 코드를 사용하여 열거할 수 있습니다. 또한 로드를 보고할 때도 트랜잭션이 사용됩니다(예: 초당 트랜잭션 수).

각 요청과 전체 웹 테스트 사례 자체에 추가할 수 있는 또 다른 조정 사항은 설명입니다. 설명을 추가하려면 요청을 마우스 오른쪽 단추로 클릭하고 설명 삽입(Insert Comment)을 클릭합니다. 설명은 요청 사이에 표시되며 전송된 데이터와 추가할 수 있는 응답 유효성 검사를 문서화하는 수단을 제공합니다.

웹 테스트 사례 실행

테스트를 기록한 후에는 테스트 실행을 시작할 수 있습니다. 프로젝트 내의 모든 테스트를 실행하려면 단순히 프로젝트를 실행하면 됩니다. 이렇게 하면 테스트 결과(Test Results) 창이 열리고 진행 중인 테스트는 보류 중인 것으로 표시되며 실행이 완료된 테스트는 통과/실패(Passed/Failed)로 표시됩니다. 또한 테스트 관리자(Test Manager) 및 테스트 보기(Test View) 창에서 테스트를 선택하고 실행할 수 있습니다.

그림 6. 테스트 선택 및 실행

또한 개별 웹 테스트 파일(테스트 사례 또는 테스트 기능)을 열고 실행(Run) 단추를 클릭하여 이러한 파일을 실행할 수도 있습니다.

그림 7. 실행 설정 대화 상자

또한 표준 인증 방법을 사용하여 대상 사이트에 로그온하기 위한 자격 증명을 요청에서 제공할 수 있습니다. 자격 증명을 위한 대화 상자를 사용하여 데이터 소스에서 로그인 데이터를 로드할 수 있습니다.

요청의 각 결과가 저장되며 각 요청을 선택하여 결과 페이지의 HTML 또는 원시 요청/응답 텍스트를 표시함으로써 세부 사항을 탐색할 수 있습니다.

그림 8. 테스트 결과 뷰어

테스트 실행 도중에 웹 테스트 엔진은 페이지의 모든 URL을 검사하여 유효한 링크인지 확인합니다. 이러한 링크는 요청 아래의 하위 노드로 나타나며 해당 URL에 대한 요청에서 반환한 HTTP 상태가 각 링크에서 표시됩니다.

요청 규칙

응답 페이지에서 유효한 하이퍼링크를 검사하는 것이 유용한 기능이기는 하지만 페이지가 올바르게 작동하는지 검증하는 데 있어 충분하지는 않습니다. 예를 들어, 유효한 자격 증명이 입력되면 웹 테스트는 로그인이 성공적이었는지 확인해야 합니다. 마찬가지로 자격 증명이 유효하지 않은 경우 적절한 오류 메시지가 페이지에 표시되도록 해야 합니다. 이를 지원하기 위해 각 웹 요청은 추출 규칙과 유효성 검사 규칙을 포함할 수 있습니다.

추출 규칙

추출 규칙은 나중에 요청 내에서 응답 값을 사용할 수 있도록 응답 값을 캡처합니다. 전체 HTTP 응답을 수동으로 구문 분석하는 대신에 추출 규칙은 응답 내의 측정 데이터 항목에 초점을 맞출 수 있는 수단을 제공합니다. 추출된 데이터 항목은 유효성을 검사하거나 후속 포스트 백(post back)에서 다시 사용될 수 있습니다. 이 문서의 기록된 예제는 로그온 시에 자동으로 추출 규칙에 추가되었습니다.

그림 9. 요청 사이에 연결할 수 있는 추출 규칙

이 규칙은 웹 테스트 사례의 두 번째 요청에서 데이터가 포스트 백(post back)되는 ExtractHiddenFields 규칙입니다. 후속 요청 도중에 이 데이터는 페이지의 숨겨진 필드에 다시 전송됩니다. 다른 추출 규칙 옵션으로는 ExtractAttributeValue, ExtractHttpHeader, ExtractRegularExpression 및 ExtractText가 있습니다. 자동으로 기록된 숨겨진 필드 데이터에 의존하는 대신에 필요에 따라 추출 규칙을 수동으로 추가하고 사용자 지정할 수 있습니다.

유효성 검사 규칙

유효성 검사 규칙을 사용하면 테스트 작성자는 전체 HTTP 응답을 검사하여 올바른지 확인할 수 있습니다. 예를 들어, 자격 증명이 유효할 경우 LOGOUT 하이퍼링크와 "Welcome <username>"이 HTML 응답에 표시되어야 합니다. 응답에서 이러한 항목을 검사하는 유효성 검사 규칙을 추가해야 합니다. 유효성 검사 규칙은 응답 본문에서 이 텍스트가 표시되는지 확인합니다.

그림 10. LOGOUT을 검사하는 유효성 검사 규칙

특정 규칙이 실패할 경우 요청은 실패한 것으로 표시되며 실패한 내용에 대한 설명이 자세히(Details) 탭에 제공됩니다.

그림 11. 유효성 검사 및 추출 규칙 결과 표시

이러한 유형의 유효성 검사 규칙은 ValidationRuleFindText입니다. 이 규칙은 전체 응답 본문을 검색하여 지정된 텍스트를 찾습니다. 복잡한 검색을 처리하기 위해 ValidationRuleFindText의 일부로 정규식이 지원됩니다.

ValidationRuleFindText 외에도 기본 제공 유효성 검사 규칙에는 ValidationRuleRequestTime, ValidationRuleRequiredAttributeValue 및 ValidationRuleRequiredTag가 있습니다.

데이터 소스에 테스트 데이터 바인딩

유효성 검사 및 추출 규칙은 둘 다 거의 모든 노드의 속성(Properties) 창에서 텍스트 입력 기능을 제공합니다. 그러나 Visual Studio 웹 테스트를 강력하게 만드는 것은 데이터베이스에서 텍스트를 가져올 수 있다는 점입니다. 따라서 이 문서의 로그온 예제에서 새 사용자를 정의할 수 있으며 지정된 강력한 암호 요구 사항을 따르지 않는 약한 암호 모음이 허용되지 않는지 확인할 수 있습니다.

데이터 소스를 사용하여 테스트하려면 웹 테스트의 도구 모음에서 데이터 소스 추가(Add Data Source)를 클릭합니다. 표시되는 대화 상자에서 또한 테스트 프로젝트에 추가될 수 있는 *.mdf 파일을 사용하여 OLE DB 공급자를 지정합니다. 서버 탐색기에서 데이터베이스를 연 후에 필요한 테스트 데이터를 포함하는 테이블을 정의합니다. 그림 12에서는 기본 키, 사용자 이름 및 암호에 대한 열을 가지는 TestUser 테이블이 사용되었습니다.

그림 12. 데이터 소스에 매개 변수 할당

테스트가 데이터 소스로 구성된 후에는 그림 7에 나온 실행 설정 편집(Edit Run Settings) 대화 상자로 돌아가서 실행 계수를 데이터 소스 행당 한 번 실행(one run per data source row)으로 변경해야 합니다. 이렇게 하면 새로 구성된 데이터 소스의 각 행에 대해 테스트가 반복되고 각 실행 도중에 데이터 소스와 연관된 매개 변수에는 특정 행의 열에 있는 값이 할당됩니다.

웹 테스트 코드 생성

지금까지 살펴본 모든 기능을 활용할 때는 코드를 작성할 필요가 없었습니다. 그러나 코드를 사용하여 추가 웹 테스트 사용자 지정을 수행할 수 있습니다. 테스트 내에서 루프나 분기와 같은 구문을 처리하거나 다른 웹 테스트를 호출하려면 이러한 사용자 지정이 필요합니다. VSTS 웹 테스트는 특정 테스트 사례에 대한 코드를 생성하는 기능을 제공합니다. 웹 테스트 사례의 도구 모음에는 코드 생성(Generate Code) 단추가 있습니다. 이 단추를 클릭하면 테스트 이름을 묻는 메시지가 표시된 다음 웹 사례에 해당하는 CS/VB 파일이 생성됩니다. 생성된 코드에는 추가되었을 수 있는 각 유효성 검사 및 추출 규칙이 포함되어 있습니다. 또한 뷰 상태와 같은 데이터가 설정되어 웹 요청의 일부로 전달됩니다. 앞에서 설명된 테스트 사례의 생성된 코드는 다음과 같습니다.

namespace HelloWorldWebSite.Test
{
using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.QualityTools.WebTestFramework;
using Microsoft.VisualStudio.QualityTools.WebTestFramework.Rules;


public class LogonCoded : WebTest
{

public LogonCoded()
{
}

public override IEnumerator<WebTestRequest> GetRequestEnumerator()
{
WebTestRequest request1 =
new WebTestRequest("http://localhost:4955/HelloWorldWebSite");
request1.ThinkTime = 17;
ExtractHiddenFields rule1 = new ExtractHiddenFields();
rule1.ContextParameterName = "1";
request1.ExtractValues +=
new EventHandler<ExtractionEventArgs>(rule1.Extract);
yield return request1;

// Redirect to the default page.

WebTestRequest request2 =
new WebTestRequest(
"http://localhost:4955/HelloWorldWebSite/default.aspx");
request2.ThinkTime = 7;
request2.Method = "POST";
BindHiddenFields request2BindHiddenFields =
new.BindHiddenFields();
request2BindHiddenFields.HiddenFieldGroup = "1";
request2.PreRequest +=
new EventHandler<PreRequestEventArgs>(
request2BindHiddenFields.PreRequest);
FormPostHttpBody request2Body = new FormPostHttpBody();
request2Body.FormPostParameters.Add(
"ctl00$Main$LoginArea$Login1$UserName", "Administrator");
request2Body.FormPostParameters.Add(
"ctl00$Main$LoginArea$Login1$Password", "G00d-P@ssw0rd");
request2Body.FormPostParameters.Add(
"ctl00$Main$LoginArea$Login1$LoginButton.x", "45");
request2Body.FormPostParameters.Add(
"ctl00$Main$LoginArea$Login1$LoginButton.y", "5");
request2.Body = request2Body;
ValidationRuleFindText rule2 = new ValidationRuleFindText();
rule2.FindText = "Administrator";
rule2.PassIfTextFound = true;
request2.ValidateResponse +=
new EventHandler<ValidationEventArgs>(rule2.Validate);
ValidationRuleFindText rule3 = new ValidationRuleFindText();
rule3.FindText = "LOGOUT";
rule3.PassIfTextFound = true;
rule3.IgnoreCase = true;
request2.ValidateResponse +=
new EventHandler<ValidationEventArgs>(rule3.Validate);
ValidationRuleRequestTime rule4 =
new ValidationRuleRequestTime();
rule4.MaxRequestTime = 500;
request2.ValidateResponse +=
new EventHandler<ValidationEventArgs>(rule4.Validate);
yield return request2;

// Logon using valid credentials and verify successful logon.

WebTestRequest request3 =
new WebTestRequest(
"http://localhost:4955/HelloWorldWebSite/default.aspx");
request3.ThinkTime = 17;
request3.Method = "POST";
FormPostHttpBody request3Body = new FormPostHttpBody();
request3Body.FormPostParameters.Add(
"__EVENTTARGET", "ctl00$LoginStatus1$ctl00");
request3Body.FormPostParameters.Add(
"__EVENTARGUMENT", "");
request3Body.FormPostParameters.Add(
"__VIEWSTATE", ...);
request3.Body = request3Body;
ExtractHiddenFields rule5 = new ExtractHiddenFields();
rule5.ContextParameterName = "1";
request3.ExtractValues +=
new EventHandler<ExtractionEventArgs>(rule5.Extract);
yield return request3;

// Logout

WebTestRequest request4 =
new WebTestRequest(
"http://localhost:4955/HelloWorldWebSite/default.aspx");
request4.Method = "POST";
BindHiddenFields request4BindHiddenFields =
new BindHiddenFields();
request4BindHiddenFields.HiddenFieldGroup = "1";
request4.PreRequest +=
new EventHandler<PreRequestEventArgs>(
request4BindHiddenFields.PreRequest);
FormPostHttpBody request4Body = new FormPostHttpBody();
request4Body.FormPostParameters.Add(
"ctl00$Main$LoginArea$Login1$UserName", "IMontoya");
request4Body.FormPostParameters.Add(
"ctl00$Main$LoginArea$Login1$Password", "bad-password");
request4Body.FormPostParameters.Add(
"ctl00$Main$LoginArea$Login1$LoginButton.x", "64");
request4Body.FormPostParameters.Add(
"ctl00$Main$LoginArea$Login1$LoginButton.y", "10");
request4.Body = request4Body;
ValidationRuleFindText rule6 = new ValidationRuleFindText();
rule6.FindText = "LOGIN";
rule6.IgnoreCase = true;
rule6.PassIfTextFound = true;
request4.ValidateResponse +=
new EventHandler<ValidationEventArgs>(rule6.Validate);
ValidationRuleFindText rule7 = new ValidationRuleFindText();
rule7.FindText = "LOGOUT";
rule7.IgnoreCase = true;
rule7.PassIfTextFound = false;
request4.ValidateResponse +=
new EventHandler<ValidationEventArgs>(rule7.Validate);
yield return request4;

// Logon using invalid credentials and verify
// unsuccessful logon.
}
}
}

C# 프로젝트의 경우 새로운 C# 2.0 반복기가 사용됩니다. 각 요청 뒤에서 코드는 한 요청을 다음 요청과 분리하는 yield return 문을 통해 다음 웹 요청을 반환합니다.

사용자 지정을 수행하지 않으려는 경우에는 코드를 생성할 이유가 없겠지만 이 작업을 미리 연습하면 나중에 특정 웹 테스트 사례나 여러 사례를 약간의 리팩토링과 함께 사용자 정의하는 데 큰 도움이 될 것입니다.

VSTS 웹 테스트 확장

대부분의 일반 웹 테스트 시나리오에서는 사용 가능한 요청 규칙과 생성된 웹 테스트에서 사용자 지정 코드를 작성하는 기능만으로 충분합니다. 그러나 경우에 따라서는 사용자 지정 유효성 검사 및 추출 규칙을 만들거나 사용자 지정 웹 테스트 플러그 인을 코딩하여 VSTS 웹 테스트를 확장하는 것이 바람직할 수 있습니다. 이러한 확장은 별도의 어셈블리에 정의되어야 하며 여러 웹 테스트 프로젝트에서 사용할 수 있습니다. 이러한 확장이 정의된 후에는 웹 테스트의 프로젝트가 새 웹 테스트 확장 어셈블리를 참조할 수 있으며 추가(Add) 대화 상자의 요청 선택에서 항목으로 표시됩니다.

유효성 검사 및 추출 규칙에 대한 대화 상자뿐만 아니라 요청 및 테스트 플러그 인에 대한 대화 상자도 사용할 수 있습니다. 요청 콜백을 각 요청에 별도로 추가하여 요청에 대한 사전 및 사후 인터셉트를 수행할 수 있습니다. 테스트 콜백은 전체 요청 집합에서 사전 및 사후 인터셉트 코드를 실행합니다. 테스트 콜백은 처음에는 테스트 사례의 시작 부분에서 호출된 다음 동일한 테스트 사례의 끝 부분에서 다시 호출됩니다. 예를 들어, 테스트의 모든 웹 페이지가 XHTML을 따르는지 검사하는 콜백이나 각 웹 요청에서 사용할 쿠키를 설정하는 콜백을 정의한다고 가정해 봅니다. 이 유효성 검사를 수행하는 플러그 인이 요청 콜백인 경우 테스트 내의 각 요청에 개별적으로 추가할 수 있습니다. 또는 콜백은 사전 테스트 실행 단계에서 모든 요청에 대한 유효성 검사를 연결하는 테스트 콜백이 될 수 있습니다. 다음 단계는 웹 테스트 콜백을 만드는 과정을 보여 줍니다.

  1. WebTestFramework라는 새 클래스 라이브러리 프로젝트를 만듭니다.
  2. Microsoft.VisualStudio.QualityTools.UnitTestFrameworkMicrosoft.VisualStudio.QualityTools.WebTestFramework에 대한 참조를 추가합니다.
  3. Microsoft.VisualStudio.QualityTools.WebTestFramework.WebTestPlugin에서 파생된 ValidationRuleXHTML이라는 새 클래스를 정의합니다.
  4. 추상 메서드 PreWebTest()PostWebTest()를 구현합니다.

마지막 두 개의 메서드는 첫 번째 매개 변수가 sender이고 두 번째 인수가 PreWebTestEventArgs/PostWebTestEventArgs인 표준 이벤트 서명을 따릅니다. 다음은 XHTML 유효성 검사기를 만드는 방법을 보여 주는 샘플 웹 테스트 플러그 인 클래스입니다.

namespace WebTestFramework
{
public class ValidationRuleXHTML :
Microsoft.VisualStudio.QualityTools.WebTestFramework.WebTestPlugin
{
public override void PostWebTest(
object sender, PostWebTestEventArgs args)
{
// No PostWebTest processing required. Implemented
// because it is an abstract method in base class.
}

void WebTestPostRequest(
object sender, PostRequestEventArgs args)
{
// 1. Retrieve the ResponseBody from
// args.Response.ResponseBody.
// 2. Validate the ResponseBody.
// 3 .Throw an exception if the HTML is not valid XHTML.
// Be sure to set the message of the exception to be as
// descriptive as possible.
}

public override void PreWebTest(
object sender, PreWebTestEventArgs args)
{
// Register an event callback for each PostRequest
// within the test.
args.WebTest.PostRequest += WebTestPostRequest;
}
}
}

이 예제에서 PreWebTest()가 하는 일은 PostRequest 이벤트의 (WebTestPostRequest()) 대리자를 등록하는 것입니다. 이렇게 하면 웹 테스트 엔진에 의해 요청이 처리될 때마다 등록된 대리자 수신기로의 호출이 수행됩니다. 대리자의 PostRequestEventArgs 매개 변수에는 string ResponseBody 속성을 제공하는 WebTest 속성이 있습니다. 이 마지막 속성은 XHTML 검사 시에 필요한 응답 본문에 대한 액세스 권한을 제공합니다. XML 유효성 검사기와 같은 것을 사용할 때는 로드 테스트를 수행할 경우 로드를 생성할 수 있는 성능의 많이 부분이 소비된다는 것에 주의해야 합니다. 따라서 함께 사용될 경우 많은 리소스를 소비하는 유효성 검사 테스트는 로드 테스트 시나리오에 사용되지 않는 단위 테스트 안에 포함되어야 합니다.

그림 13에는 웹 테스트 플러그 인을 작성하기 위한 개체 모델이 나와 있습니다.

큰 그림으로 보려면 이미지를 클릭

그림 13. 웹 테스트 플러그 인 개체 모델(큰 그림으로 보려면 이미지를 클릭)

이 모델은 웹 테스트 플러그 인 내에서 액세스할 수 있는 기능과 웹 테스트 플러그 인에서 제공할 수 있는 유효성 검사의 개요를 보여 줍니다. 사전/사후 웹 테스트 메서드에서 웹 테스트 사례에 대한 정보를 전체적으로 액세스할 수 있습니다(예: 자격 증명 정보에 대한 액세스와 함께 테스트와 연관된 데이터 소스). 가장 중요한 것은 각 요청에서 XHTML 유효성 검사기 콜백을 연결할 수 있었던 사전/사후 요청 이벤트에 대한 액세스를 이러한 메서드가 제공한다는 점입니다.

사전 요청 및 사후 요청 이벤트 서명은 둘 다 WebTest 개체에 대한 액세스를 각각의 EventArgs 클래스를 통해 제공합니다. 또한 이러한 서명은 요청 자체의 세부 정보에 액세스하기 위한 WebTestRequest 개체에 대한 액세스를 제공합니다. PostRequestEventArgs 속성에서는 WebTestResponse 개체에 액세스하여 요청에서 반환된 데이터를 검사할 수 있습니다.

앞에서는 사용자 지정 유효성 검사 및 추출 규칙을 사용할 수도 있다는 것을 언급했습니다. 이러한 규칙을 만들려면 Microsoft.VisualStudio.QualityTools.WebTestFramework.WebTestPlugin 또는 Microsoft.VisualStudio.QualityTools.WebTestFramework.WebTestRequestPlugin 대신에 Microsoft.VisualStudio.QualityTools.WebTestFramework.ValidationMicrosoft.VisualStudio.QualityTools.WebTestFramework.ExtractionRule에서 파생시킵니다. 그림 14에는 규칙 기본 클래스의 개요가 나와 있습니다.

그림 14. 사용자 지정 추출 및 유효성 검사 규칙을 사용하여 확장

ValidationEventArgsExtractionEventArgs 클래스는 규칙의 각 Validate()Extract() 메서드에 대한 형식 매개 변수입니다. 개별 요청에서 사용될 경우 이러한 이벤트 인수는 플러그 인 방식보다 더 많은 요청 관련 데이터에 대한 직접 액세스를 제공합니다. 또한 IsValid와 같은 속성은 앞에서 설명된 웹 테스트 플러그 인의 예외 발생 메커니즘보다 향상된 오류 보고 수단을 제공합니다. 그러나 앞에서 언급한 것처럼 규칙은 전체 테스트에서 삽입하는 것이 아니라 개별 요청 단위로 삽입해야 합니다. 플러그 인 방식의 경우에는 요청 자체를 인터셉트할 수 있다는 또 다른 이점이 있습니다. 즉, 요청이 수행되고 응답이 반환된 후에만 호출되지는 않습니다. 요약하자면 모든 요청에서 유효성 검사를 제공하지 않거나 서버에 전송되기 전에 요청을 인터셉트할 필요가 없을 경우 유효성 검사 및 추출 규칙을 사용합니다.

브라우저 사용자 인터페이스 테스트

JavaScript, ActiveX 컨트롤 및 애플릿을 통한 웹 요청은 VSTS 웹 테스트 기능 내에서 지원되지 않습니다. 마찬가지로 VSTS 웹 테스트는 사용자 인터페이스(UI) 테스트 도구가 되도록 설계되지 않았습니다. VSTS 웹 테스트는 클라이언트 쪽 JavaScript를 실행하지 않으며 결과를 확인하지 않습니다. 간단한 메뉴 클릭 및 확장 유형의 작업도 이 도구로 시뮬레이트할 수 없습니다. 또한 특정 브라우저 클라이언트를 서버에 대해 시뮬레이트하더라도 해당 클라이언트 브라우저 내에서 응답이 올바르게 렌더링되는지 확인하는 과정에서 아무 작업도 수행하지 않습니다(Microsoft Internet Explorer인 경우에도 마찬가지임). VSTS 웹 테스트는 회선 기반 테스트 프로토콜입니다. VSTS 웹 테스트는 회선을 통해 주고 받는 데이터를 확인할 뿐이며 브라우저에 의해 데이터가 렌더링되는 방법을 테스트할 수 있는 기능은 제공하지 않습니다.

이러한 유형의 테스트를 제공하는 것은 번거롭고 힘든 일입니다. 그러나 특정 상황에서 고려할 수 있는 몇 가지 방법이 있습니다. 동일한 응답이 여러 번 발생할 경우에는 브라우저 내에서 응답이 동일한 방식으로 렌더링 및 작동한다고 가정하는 것이 타당합니다. 따라서 특정 응답이 올바른지 수동으로 확인할 경우(예를 들어, JavaScript가 제대로 작동하고 있으며 페이지가 올바르게 렌더링되는지 확인하여) 동일한 응답이 다음 번에 올바르게 작동할 것이라 예상할 수 있습니다. 이 원칙을 사용하면 응답을 시각적으로 확인하여 스크립트가 적절하게 작동하는지 수동으로 검사할 수 있습니다. 이제 약간의 데이터 변경(예: 데이터 시간, 사용자 이름 또는 광고 변경)을 처리하는 와일드카드를 사용하여 유사한 응답을 검사하는 유효성 검사 테스트를 만들 수 있습니다. 이후에 테스트가 실행될 때 페이지가 변경된 경우 응답을 다시 확인하고 테스트를 적절하게 업데이트해야 하며 따라서 일정 수준의 변경 제어가 페이지에 제공됩니다. 이러한 테스트는 팀 전체에서 배포되지는 않지만 적절한 기본 테스트 메커니즘을 제공하며 변경을 제어하도록 만듭니다.

테스트 기반 개발

이 문서에서는 테스트를 먼저 작성한 다음 이러한 테스트를 충족하는 페이지를 작성하는 테스트 기반 개발(TDD) 방식을 사용하는 것이 아니라 기존 웹 사이트를 테스트했습니다. 테스트 기반 방법론을 사용하지 않은 주된 이유는 VSTS 웹 테스트의 기록 기능 때문이었습니다. 각 요청에 대한 URL을 수동으로 입력하는 대신에 웹 사이트를 탐색하고 웹 레코드에서 각 요청을 테스트에 자동으로 저장하는 방법이 사용되었습니다.

기록 기능은 각 요청을 수동으로 입력할 필요가 없다는 중요한 이점이 있습니다. 그러나 테스트 기반 방식을 활용할 수도 있습니다. 이렇게 하려면 먼저 진행 중인 요청에 해당하는 모든 링크와 요청을 제출하는 모든 단추를 포함하는 페이지를 디자인합니다. 또한 이 과정에서 코딩을 최소한 적게 사용해야 합니다. 그런 다음 사이트 탐색을 기록하고 적절한 요청을 테스트 사례 구조에 추가합니다. 마지막으로 웹 테스트 사례를 열고 유효성 검사 및 추출 규칙을 포함하도록 수정합니다. 이 시점에서 웹 테스트 사례를 실행하면 실패 결과가 발생해야 합니다. 이는 규칙을 이행하는 코드가 추가되지 않았기 때문입니다. 이제 TDD 방식에서 가리키는 것처럼 테스트를 작성하는 단계에서 코드를 작성하는 단계로 건너갑니다.

예를 들어, TDD를 사용한 로그인 시나리오를 가정해 봅니다. 처음에 개발자는 로그인 페이지를 작성하고 자격 증명을 전송하는 로그인(Login) 단추를 추가합니다. 그런 다음에는 웹 레코더를 열고 전송 요청을 기록하는 작업이 수행됩니다. 사용자 ID가 응답에 표시되는지 확인하고 로그아웃 링크가 있는지 확인하기 위해 구현을 작성하기 전에 유효성 검사를 스텁에 추가합니다. 이제 테스트를 실행하면 테스트가 실패한다는 것과 테스트한 대상의 구현을 작성해야 한다는 것을 알 수 있습니다.

결론

이 문서에서는 VSTS 웹 테스트 기능을 살펴보았습니다. 대상 웹 사이트에 대한 작업을 기록하여 생성된 웹 테스트 사례를 포함하는 테스트 프로젝트를 작성하는 방법을 설명했으며 이 과정에서 VSTS 웹 테스트를 설정하는 것이 아주 쉽다는 사실과 테스트의 많은 부분이 코드를 전혀 작성할 필요 없이 지원된다는 사실을 알게 되었습니다. QA 엔지니어가 제품에 액세스할 수 있을 때까지 기다리는 대신에 개발 주기의 초기에 테스트를 자주 실행할 수 있도록 한다는 점에서 이것은 매우 중요한 기능입니다.

VSTS 웹 테스트가 단순히 기록 작업을 의미하지는 않습니다. 기록된 테스트를 확장할 수 있는 많은 가능성이 있습니다. 테스트 코드를 생성할 수 있기 때문에 특수한 사용자 지정이 필요한 경우 코딩된 테스트를 쉽게 활용할 수 있습니다. 또한 코드가 아주 간단하기 때문에 대부분의 개발자는 마우스를 사용하는 UI 대신에 코드에 의존하여 웹 테스트 사례를 만들 수 있습니다. VSTS 웹 테스트를 간단하게 확장할 수 있다는 사실은 다른 필요한 기능을 손쉽게 추가할 수 있는 뛰어난 플랫폼이 제공된다는 것을 의미합니다.

Posted by 퓨전마법사
,