Visual Studio를 사용하여 Azure Functions 개발
Visual Studio를 사용하면 C# 클래스 라이브러리 함수를 개발, 테스트하여 Azure에 배포할 수 있습니다. Azure Functions를 처음 사용하는 경우, Azure Functions 소개를 참조하세요.
Visual Studio로 함수를 개발하면 다음과 같은 이점이 있습니다.
- 로컬 개발 컴퓨터에서 함수를 편집, 빌드 및 실행합니다.
- Azure Functions 프로젝트를 Azure에 직접 게시하고 필요에 따라 Azure 리소스를 만듭니다.
- C# 특성을 사용하여 C# 코드에서 직접 함수 바인딩을 선언합니다.
- 미리 컴파일된 C# 함수를 개발하고 배포합니다. 미리 컴파일된 함수는 C# 스크립트 기반 함수보다 더 뛰어난 콜드 부팅 성능을 제공합니다.
- Visual Studio 개발의 모든 이점을 누리면서 C#에서 함수를 코딩합니다.
이 문서에서는 Visual Studio를 사용하여 C# 클래스 라이브러리 함수를 개발하고 Azure에 게시하는 방법에 대해 자세히 설명합니다. 이 문서를 읽기 전에 Visual Studio용 Functions 빠른 시작을 읽는 것이 좋습니다.
별도로 언급하지 않는 한, 표시된 프로시저와 예제는 Visual Studio 2022에 대한 것입니다. Visual Studio 2022 릴리스에 대한 자세한 내용은 릴리스 정보 또는 미리 보기 릴리스 정보를 참조하세요.
사전 요구 사항
Azure Functions 도구. Azure Functions 도구를 추가하려면 Visual Studio 설치 시 Azure 개발 워크로드를 포함합니다. Visual Studio 2017을 사용하는 경우 몇 가지 추가 설치 단계를 수행해야 할 수 있습니다.
Azure Storage 계정과 같이 필요한 다른 리소스는 게시 프로세스 중에 구독에서 만들어 집니다.
-
Azure를 구독하고 있지 않다면 시작하기 전에 Azure 체험 계정을 만듭니다.
Azure Functions 프로젝트 만들기
Visual Studio의 Azure Functions 프로젝트 템플릿은 Azure에서 함수 앱에 게시할 수 있는 C# 클래스 라이브러리 프로젝트를 만듭니다. 함수 앱을 사용하면 함수를 논리 단위로 그룹화하여 더 쉽게 리소스를 관리, 배포, 크기 조정 및 공유할 수 있습니다.
Visual Studio 메뉴에서 파일>새로 만들기>프로젝트를 차례로 선택합니다.
새 프로젝트 만들기에서 검색 상자에 함수를 입력하고, Azure Functions 템플릿을 선택한 다음, 다음을 선택합니다.
새 프로젝트 구성에서 프로젝트에 대한 프로젝트 이름을 입력한 다음, 만들기를 선택합니다. 함수 앱 이름은 C# 네임스페이스로 유효해야 하므로 밑줄, 하이픈 또는 기타 영숫자가 아닌 문자는 사용하지 마세요.
새 Azure Functions 애플리케이션 만들기 설정에 대해서는 다음 표의 값을 사용합니다.
설정 값 설명 .NET 버전 .NET 6 이 값은 Azure Functions 런타임 버전 4.x에서 In-Process로 실행되는 함수 프로젝트를 만듭니다. Azure Functions 1.x는 .NET Framework를 지원합니다. 자세한 내용은 Azure Functions 런타임 버전 개요를 참조하세요. 함수 템플릿 HTTP 트리거 이 값은 HTTP 요청에 의해 트리거되는 함수를 만듭니다. 스토리지 계정(AzureWebJobsStorage) 스토리지 에뮬레이터 Azure의 함수 앱에는 스토리지 계정이 필요하기 때문에 Azure에 프로젝트를 게시할 때 할당되거나 생성됩니다. HTTP 트리거는 Azure Storage 계정 연결 문자열을 사용하지 않습니다. 다른 모든 트리거 형식에는 유효한 Azure Storage 계정 연결 문자열이 필요합니다. 권한 부여 수준 익명 만들어진 함수를 모든 클라이언트에서 키를 제공하지 않고 트리거할 수 있습니다. 이 권한 부여 설정을 통해 새 함수를 쉽게 테스트할 수 있습니다. 키 및 권한 부여에 대한 자세한 내용은 권한 부여 키 및 HTTP 및 웹후크 바인딩을 참조하세요. 권한 부여 수준을 익명으로 설정했는지 확인합니다. 기본 수준인 함수를 선택하면 함수 엔드포인트에 액세스하도록 요구하는 요청에 함수 키를 제공해야 합니다.
만들기를 선택하여 함수 프로젝트 및 HTTP 트리거 함수를 만듭니다.
Azure Functions 프로젝트를 만든 후 프로젝트 템플릿은 C# 프로젝트를 만들고, Microsoft.NET.Sdk.Functions
NuGet 패키지를 설치하고, 대상 프레임워크를 설정합니다. 새 프로젝트에는 다음 파일이 포함됩니다.
host.json: 함수 호스트를 구성할 수 있습니다. 이러한 설정은 로컬 및 Azure에서 실행할 때 모두 적용됩니다. 자세한 내용은 host.json 참조를 참조하세요.
local.settings.json: 함수를 로컬로 실행할 때 사용되는 설정을 유지합니다. 이러한 설정은 Azure에서 실행하는 경우에는 사용되지 않습니다. 자세한 내용은 로컬 설정 파일을 참조하세요.
중요
local.settings.json 파일에 암호가 있을 수 있으므로 프로젝트 원본 제어에서 해당 파일을 제외해야 합니다. 이 파일에 대한 출력 디렉터리로 복사 설정은 새 내용이면 복사로 설정해야 합니다.
자세한 내용은 Functions 클래스 라이브러리 프로젝트를 참조하세요.
로컬 설정
Azure의 함수 앱에서 실행하는 경우 함수에 필요한 설정은 앱 설정에 안전하게 저장됩니다. 로컬 개발 중에 이러한 설정은 local.settings.json 파일의 Values
개체에 대신 추가됩니다. local.settings.json 파일은 로컬 개발 도구에서 사용하는 설정도 저장합니다.
local.settings.json에는 연결 문자열과 같은 비밀이 포함될 수 있으므로 원격 리포지토리에 저장해서는 안 됩니다. 로컬 설정에 대해 자세히 알아보려면 로컬 설정 파일을 참조하세요.
Visual Studio는 프로젝트를 게시할 때 local.settings.json의 설정을 자동으로 업로드하지 않습니다. 이러한 설정이 Azure의 함수 앱에도 있는지 확인하려면 프로젝트를 게시한 후에 이를 업로드합니다. 자세한 내용은 함수 앱 설정을 참조하세요. ConnectionStrings
컬렉션의 값은 전혀 게시되지 않습니다.
코드는 함수 앱 설정 값을 환경 변수로 읽을 수도 있습니다. 자세한 내용은 환경 변수를 참조하세요.
로컬 개발에 대한 프로젝트 구성
함수 런타임에서 Azure Storage 계정을 내부적으로 사용합니다. HTTP 및 웹후크 이외의 모든 트리거 형식에 대해 Values.AzureWebJobsStorage
키를 유효한 Azure Storage 계정 연결 문자열에 설정해야 합니다. 함수 앱은 프로젝트에 필요한 AzureWebJobsStorage
연결 설정에 Azurite 에뮬레이터를 사용할 수도 있습니다. 에뮬레이터를 사용하려면 이러한 AzureWebJobsStorage
값을 UseDevelopmentStorage=true
로 설정합니다. 배포하기 전에 이 설정을 실제 스토리지 계정 연결로 변경해야 합니다. 자세한 내용은 로컬 스토리지 에뮬레이터를 참조하세요.
스토리지 계정 연결 문자열을 설정하려면 다음을 수행합니다.
Azure Portal에서 스토리지 계정으로 이동합니다.
액세스 키 탭의 보안 + 네트워킹 아래에 있는 연결 문자열key1을 복사합니다.
프로젝트에서 local.settings.json 파일을 열고
AzureWebJobsStorage
키의 값을 복사한 연결 문자열로 설정합니다.이전 단계를 반복하여 함수에 필요한 다른 연결에 대한
Values
배열에 고유 키를 추가합니다.
프로젝트에 함수 추가
C# 클래스 라이브러리 함수에서, 함수에 사용된 바인딩은 코드에 특성을 적용하여 정의됩니다. 제공된 템플릿에서 함수 트리거를 만들면 트리거 특성이 적용됩니다.
솔루션 탐색기에서 프로젝트 노드를 마우스 오른쪽 단추로 클릭하고 추가>새 항목을 차례로 선택합니다.
Azure Function을 선택하고 클래스의 이름을 입력한 다음 추가를 선택합니다.
사용자의 트리거를 선택하고, 바인딩 속성을 설정한 후, 추가를 선택합니다. 다음 예제에서는 Queue Storage 트리거 함수를 만들기 위한 설정을 보여 줍니다.
그런 다음, Azure 스토리지 에뮬레이터 중에서 선택하거나 프로비전된 Azure 스토리지 계정을 참조하라는 메시지가 표시됩니다.
이 트리거 예제에서는 키 이름이
QueueStorage
인 연결 문자열을 사용합니다. local.settings.json 파일에 저장된 이 키는 Azurite 에뮬레이터 또는 Azure 스토리지 계정을 참조합니다.새로 추가된 클래스를 검사합니다.
FunctionName
특성을 사용하는 정적Run()
메소드가 표시됩니다. 이 특성은 메서드가 함수에 대한 진입점임을 나타냅니다.예를 들어 다음 C# 클래스는 기본 Queue Storage 트리거 함수를 나타냅니다.
using System; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Host; using Microsoft.Extensions.Logging; namespace FunctionApp1 { public static class Function1 { [FunctionName("QueueTriggerCSharp")] public static void Run([QueueTrigger("myqueue-items", Connection = "QueueStorage")]string myQueueItem, ILogger log) { log.LogInformation($"C# Queue trigger function processed: {myQueueItem}"); } } }
바인딩 고유 특성은 진입점 메서드에 적용되는 각 바인딩 매개 변수에 적용됩니다. 특성은 매개 변수로 바인딩 정보를 사용합니다. 이전 예제에서 첫 매개 변수는 Queue Storage 트리거 함수를 나타내는 QueueTrigger
특성이 적용되었습니다. 큐 이름 및 연결 문자열 설정 이름은 QueueTrigger
특성에 매개 변수로 전달됩니다. 자세한 내용은 Azure Functions의 Azure Queue Storage 바인딩을 참조하세요.
위의 프로시저를 사용하여 함수 앱 프로젝트에 더 많은 함수를 추가할 수 있습니다. 프로젝트의 각 함수는 다른 트리거를 가질 수 있지만 함수에는 정확히 하나의 트리거가 있어야 합니다. 자세한 내용은 Azure Functions 트리거 및 바인딩 개념을 참조하세요.
바인딩 추가
트리거와 마찬가지로 입력 및 출력 바인딩이 바인딩 특성으로 함수에 추가됩니다. 다음과 같이 함수에 바인딩을 추가합니다.
로컬 개발에 대한 프로젝트를 구성했는지 확인합니다.
바인딩에 대한 참조 문서에서 바인딩별 NuGet 패키지 요구 사항을 찾아 특정 바인딩에 적절한 NuGet 확장 패키지를 추가합니다. 예를 들어 Event Hubs 바인딩 참조 문서에서 Event Hubs 트리거에 대한 패키지 요구 사항을 찾습니다.
패키지 관리자 콘솔에서 다음 명령을 사용하여 특정 패키지를 설치합니다.
Install-Package Microsoft.Azure.WebJobs.Extensions.<BINDING_TYPE> -Version <TARGET_VERSION>
이 예제에서
<BINDING_TYPE>
을 바인딩 확장과 관련된 이름으로 바꾸고,<TARGET_VERSION>
을3.0.0-beta5
와 같은 특정 버전의 패키지로 바꿉니다. 유효한 버전은 NuGet.org의 개별 패키지 페이지에 나열되어 있습니다. Functions 런타임 1.x 또는 2.x에 해당하는 주 버전은 바인딩의 참조 문서에 지정되어 있습니다.바인딩에 필요한 앱 설정이 있는 경우 로컬 설정 파일의
Values
컬렉션에 추가합니다.함수는 로컬로 실행될 때 이러한 값을 사용합니다. 함수가 Azure의 함수 앱에서 실행될 때 함수 앱 설정이 사용됩니다.
메서드 서명에 적절한 바인딩 특성을 추가합니다. 다음 예제에서 큐 메시지는 함수를 트리거하고, 출력 바인딩은 다른 큐와 동일한 텍스트가 있는 새 큐 메시지를 만듭니다.
public static class SimpleExampleWithOutput { [FunctionName("CopyQueueMessage")] public static void Run( [QueueTrigger("myqueue-items-source", Connection = "AzureWebJobsStorage")] string myQueueItem, [Queue("myqueue-items-destination", Connection = "AzureWebJobsStorage")] out string myQueueItemCopy, ILogger log) { log.LogInformation($"CopyQueueMessage function processed: {myQueueItem}"); myQueueItemCopy = myQueueItem; } }
Queue Storage에 대한 연결은
AzureWebJobsStorage
설정에서 가져옵니다. 자세한 내용은 특정 바인딩에 대한 참조 문서를 참조하세요.
Functions에서 지원되는 바인딩의 전체 목록은 지원되는 바인딩을 참조하세요.
로컬로 함수 실행
Azure Functions Core 도구를 사용하면 로컬 개발 컴퓨터에서 Azure Functions 프로젝트를 실행할 수 있습니다. F5 키를 눌러 Functions 프로젝트를 디버그하면 로컬 Functions 호스트(func.exe)가 로컬 포트(일반적으로 7071)에서 수신 대기를 시작합니다. 호출 가능한 모든 함수 엔드포인트는 출력에 기록되며, 이러한 엔드포인트를 사용하여 함수를 테스트할 수 있습니다. 자세한 내용은 Azure Functions Core 도구로 작업을 참조하세요. Visual Studio에서 처음으로 함수를 시작할 때 이러한 도구를 설치하라는 메시지가 표시됩니다.
디버그 모드로 Visual Studio에서 함수를 시작하려면:
F5 키를 누릅니다. 메시지가 표시되면 Visual Studio에서 Azure Functions Core(CLI) 도구를 다운로드하여 설치하도록 요구하는 요청을 수락합니다. 또한 도구에서 HTTP 요청을 처리할 수 있도록 방화벽 예외를 사용하도록 설정해야 할 수도 있습니다.
프로젝트가 실행 중인 상태에서 배포된 기능을 테스트할 때처럼 코드를 테스트합니다.
디버그 모드에서 Visual Studio를 실행하면 중단점이 예상대로 적중됩니다.
Visual Studio를 사용하는 테스트 시나리오에 관한 자세한 내용은 함수 테스트를 참조하세요.
Azure에 게시
Visual Studio에서 게시하는 경우 다음 두 가지 배포 방법 중 하나를 사용합니다.
- 웹 배포: Windows 앱을 패키징하고 모든 IIS 서버에 배포합니다.
- 패키지 실행이 사용하도록 설정된 Zip 배포: Azure Functions 배포에 권장됩니다.
다음 단계를 사용하여 Azure의 함수 앱에 프로젝트를 게시합니다.
솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 게시를 선택합니다. 대상에서 Azure를 선택한 후 다음을 선택합니다.
Windows에서 실행되는 함수 앱을 만드는 특정 대상에 대해 Azure Function 앱(Windows)을 선택한 후, 다음을 선택합니다.
함수 인스턴스에서 새 Azure Function 만들기...를 선택합니다.
다음 표에 지정된 값을 사용하여 새 인스턴스를 만듭니다.
설정 값 Description 이름 전역적으로 고유한 이름 새 함수 앱을 고유하게 식별하는 이름입니다. 이 이름을 수락하거나 새 이름을 입력합니다. 유효한 문자는 a-z
,0-9
및-
입니다.구독 사용자의 구독 사용할 Azure 구독입니다. 이 구독을 수락하거나 드롭다운 목록에서 새 구독을 선택합니다. 리소스 그룹 리소스 그룹의 이름 함수 앱을 만들 리소스 그룹입니다. 드롭다운 목록에서 기존 리소스 그룹을 선택하거나 새로 만들기를 선택하여 새 리소스 그룹을 만듭니다. 계획 유형 Consumption 프로젝트를 사용량 요금제에서 실행되는 함수 앱에 게시하는 경우 함수 앱의 실행에 대한 비용만 지불합니다. 다른 호스팅 계획에는 비용이 더 많이 듭니다. 위치 App Service의 위치 사용자 또는 함수가 액세스하는 기타 서비스에 가까운 지역의 위치를 선택합니다. Azure Storage 범용 스토리지 계정 Azure 스토리지 계정은 함수 런타임에서 필요합니다. 새로 만들기를 선택하여 범용 스토리지 계정을 구성합니다. 스토리지 계정 요구 사항을 충족하는 기존 계정을 선택할 수도 있습니다. 만들기를 선택하여 Azure에서 함수 앱 및 관련된 리소스를 만듭니다. 리소스 만들기 상태는 창의 왼쪽 하단에 표시됩니다.
함수 인스턴스에서 패키지 파일에서 실행이 선택되어 있는지 확인합니다. Run-From-Package 모드를 사용하도록 설정된 상태에서 Zip 배포를 사용하여 함수 앱이 배포됩니다. Zip Deploy는 성능이 향상되므로 함수 프로젝트에 권장되는 배포 방법입니다.
마침를 선택하고 게시 페이지에서 게시를 선택하여 프로젝트 파일이 포함된 패키지를 Azure의 새 함수 앱에 배포합니다.
배포가 완료되면 Azure에서 함수 앱의 루트 URL이 게시 탭에 표시됩니다.
게시 탭의 호스팅 섹션에서 Azure Portal에서 열기를 선택합니다. 그러면 Azure Portal에서 새 함수 앱 Azure 리소스가 열립니다.
함수 앱 설정
Visual Studio는 사용자가 프로젝트를 게시할 때 이러한 설정을 자동으로 업로드하지 않습니다. local.settings.json에 추가하는 모든 설정은 Azure의 함수 앱에도 추가해야 합니다.
Azure의 함수 앱에 필요한 설정을 업로드하는 가장 쉬운 방법은 호스팅 섹션 옆에 있는 점 3개를 확장하고 프로젝트를 성공적으로 게시한 후에 표시되는 Azure App Service 설정 관리 링크를 선택하는 것입니다.
이 링크를 선택하면 새로운 애플리케이션 설정을 추가하거나 기존 애플리케이션 설정을 수정할 수 있는 함수 앱에 대한 애플리케이션 설정 대화 상자가 표시됩니다.
로컬은 local.settings.json 파일의 설정 값을 표시하며 원격은 Azure의 함수 앱에 대한 현재 설정 값입니다. 설정 추가를 선택하여 새로운 앱 설정을 만듭니다. 로컬 값 삽입 링크를 사용하여 원격 필드에 설정 값을 복사합니다. 확인을 선택하면 보류 중인 변경 내용이 로컬 설정 파일 및 함수 앱에 기록됩니다.
참고
기본적으로 local.settings.json 파일은 소스 제어에 체크인되지 않습니다. 즉, 소스 제어에서 로컬 Functions 프로젝트를 복제하는 경우 프로젝트에는 local.settings.json 파일이 없습니다. 이 경우 애플리케이션 설정 대화 상자가 예상대로 작동하도록 프로젝트 루트에서 local.settings.json 파일을 수동으로 만들어야 합니다.
또한 다음 다른 방법 중 하나로 애플리케이션 설정을 관리할 수도 있습니다.
Remote Debugging
함수 앱을 원격으로 디버그하려면 프로젝트의 디버그 구성을 게시해야 합니다. 또한 Azure의 함수 앱에서 원격 디버깅을 사용하도록 설정해야 합니다.
이 섹션에서는 릴리스 구성을 사용하여 함수 앱에 이미 게시했다고 가정합니다.
원격 디버깅 고려 사항
- 원격 디버깅은 프로덕션 서비스에서 권장되지 않습니다.
- 내 코드만 디버깅이 사용하도록 설정된 경우 이를 사용하지 않도록 설정합니다.
- 원격 디버깅 시 중단점에서 장시간 중지하지 않도록 합니다. 몇 분 이상 중지된 프로세스는 Azure에서 응답하지 않는 프로세스로 간주되어 종료되기 때문입니다.
- 디버그하는 동안 서버는 데이터를 Visual Studio로 보내며, 이로 인해 대역폭 사용 요금에 영향을 줄 수 있습니다. 대역폭 요금에 대한 자세한 내용은 Azure 가격 책정을 참조하십시오.
- 원격 디버깅은 48시간 후에 함수 앱에서 자동으로 사용하지 않도록 설정됩니다. 48시간이 지나면 원격 디버깅을 다시 사용하도록 설정해야 합니다.
디버거 연결
디버거를 연결하는 방법은 실행 모드에 따라 달라집니다. 격리된 작업자 프로세스 앱을 디버그하는 경우 현재 원격 디버거를 별도의 .NET 프로세스에 연결해야 하며 몇 가지 다른 구성 단계가 필요합니다.
완료되면 원격 디버깅을 사용하지 않도록 설정해야 합니다.
Functions 호스트를 사용하여 In Process에서 실행되는 함수 앱에 원격 디버거를 연결하려면 다음을 수행합니다.
게시 탭의 호스팅 섹션에서 줄임표(...)를 선택한 다음, 디버거 연결을 선택합니다.
아직 사용하도록 설정되지 않은 경우 Visual Studio에서 함수 앱에 연결하고 원격 디버깅을 사용하도록 설정합니다. 또한 디버거를 찾아서 앱의 호스트 프로세스에 연결합니다. 이 시점에서 함수 앱을 정상적으로 디버그할 수 있습니다.
원격 디버깅 사용 안 함
코드 원격 디버깅이 완료되면 Azure Portal에서 원격 디버깅을 사용하지 않도록 설정해야 합니다. 그렇지 않으면 원격 디버깅이 48시간 후에 자동으로 사용하지 않도록 설정됩니다.
프로젝트의 게시 탭에 있는 호스팅 섹션에서 줄임표(...)를 선택하고, Azure Portal에서 열기를 선택합니다. 이 작업은 프로젝트가 배포된 Azure Portal에서 함수 앱을 엽니다.
함수 앱의 설정 아래에서 구성을 선택하고, 일반 설정을 선택하고, 원격 디버깅을 끄기로 설정하고, 저장을 선택한 다음, 계속을 선택합니다.
함수 앱이 다시 시작되면 더 이상 원격 프로세스에 원격으로 연결할 수 없습니다. Azure Portal에서 동일한 탭을 사용하여 Visual Studio 외부에서 원격 디버깅을 사용하도록 설정할 수 있습니다.
함수 모니터링
함수 실행을 모니터링할 때는 Azure Application Insights와 함수 앱을 통합하는 방식을 사용하는 것이 좋습니다. Azure Portal에서 함수 앱을 만들 때는 이 통합이 기본적으로 자동 수행됩니다. 그러나 Visual Studio 게시 중에 함수 앱을 만들 때는 Azure에서 함수 앱 통합이 수행되지 않습니다. Application Insights를 함수 앱에 연결하는 방법은 Application Insights 통합 사용을 참조하세요.
Application Insights를 사용하여 모니터링하는 방법에 대한 자세한 내용은 Azure Functions 모니터링을 참조하세요.
테스팅 함수
이 섹션에서는 Visual Studio에서 C# 함수 앱 프로젝트를 만들고 xUnit을 사용하여 실행 및 테스트하는 방법을 설명합니다.
설치 프로그램
환경을 설정하려면 함수를 만들고 앱을 테스트합니다. 다음 단계에서는 테스트를 지원하는 데 필요한 앱 및 함수를 만들 수 있습니다.
- 새 Functions 앱을 만들고 이름을 Functions로 지정합니다.
- 템플릿에서 HTTP 함수를 만들고 이름을 MyHttpTrigger로 지정합니다.
- 템플릿에서 타이머 함수를 만들고 이름을 MyTimerTrigger로 지정합니다.
- 솔루션에서 xUnit 테스트 앱을 만들고 이름을 Functions.Tests로 지정합니다. 기본 테스트 파일을 제거합니다.
- Nuget을 사용하여 테스트 앱의 참조를 Microsoft.AspNetCore.Mvc에 추가합니다.
- Functions.Tests 앱에서 Functions 앱을 참조합니다.
테스트 클래스 만들기
이제 프로젝트가 만들어졌으므로 자동화된 테스트를 실행하는 데 사용되는 클래스를 만들 수 있습니다.
각 함수는 ILogger 인스턴스를 사용하여 메시지 로깅을 처리합니다. 일부 테스트는 메시지를 기록하지 않거나 로깅 구현 방법에 관여하지 않습니다. 기타 테스트는 테스트 통과 여부를 결정하기 위해 기록된 메시지를 평가해야 합니다.
테스트 중에 평가할 메시지의 내부 목록을 보유하는 ListLogger
라는 새 클래스를 만듭니다. 필요한 ILogger
인터페이스를 구현하려면 클래스에 범위가 필요합니다. 다음 클래스는 ListLogger
클래스에 전달할 테스트 사례에 대한 범위를 모방합니다.
Nullscope.cs라는 Functions.Tests 프로젝트에 새 클래스를 만들고 다음 코드를 입력합니다.
using System;
namespace Functions.Tests
{
public class NullScope : IDisposable
{
public static NullScope Instance { get; } = new NullScope();
private NullScope() { }
public void Dispose() { }
}
}
그런 다음 Listlogger.cs라는 Functions.Tests 프로젝트에 새 클래스를 만들고 다음 코드를 입력합니다.
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace Functions.Tests
{
public class ListLogger : ILogger
{
public IList<string> Logs;
public IDisposable BeginScope<TState>(TState state) => NullScope.Instance;
public bool IsEnabled(LogLevel logLevel) => false;
public ListLogger()
{
this.Logs = new List<string>();
}
public void Log<TState>(LogLevel logLevel,
EventId eventId,
TState state,
Exception exception,
Func<TState, Exception, string> formatter)
{
string message = formatter(state, exception);
this.Logs.Add(message);
}
}
}
ListLogger
클래스는 ILogger
인터페이스에서 계약된 대로 다음 멤버를 구현합니다.
BeginScope: 범위는 로깅에 컨텍스트를 추가합니다. 이 경우 테스트가 작동할 수 있으려면 테스트가
NullScope
클래스의 정적 인스턴스를 가리키면 됩니다.IsEnabled:
false
의 기본값이 제공됩니다.Log: 이 메서드는 제공된
formatter
함수를 사용하여 메시지의 형식을 지정하고 결과 텍스트를Logs
컬렉션에 추가합니다.
Logs
컬렉션은 List<string>
의 인스턴스이고 생성자에서 초기화됩니다.
그런 다음 LoggerTypes.cs라는 Functions.Tests 프로젝트에 새 파일을 만들고 다음 코드를 입력합니다.
namespace Functions.Tests
{
public enum LoggerTypes
{
Null,
List
}
}
이 열거형은 테스트에서 사용하는 로거 형식을 지정합니다.
이제 TestFactory.cs라는 Functions.Tests 프로젝트에 새 클래스를 만들고 다음 코드를 입력합니다.
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Primitives;
using System.Collections.Generic;
namespace Functions.Tests
{
public class TestFactory
{
public static IEnumerable<object[]> Data()
{
return new List<object[]>
{
new object[] { "name", "Bill" },
new object[] { "name", "Paul" },
new object[] { "name", "Steve" }
};
}
private static Dictionary<string, StringValues> CreateDictionary(string key, string value)
{
var qs = new Dictionary<string, StringValues>
{
{ key, value }
};
return qs;
}
public static HttpRequest CreateHttpRequest(string queryStringKey, string queryStringValue)
{
var context = new DefaultHttpContext();
var request = context.Request;
request.Query = new QueryCollection(CreateDictionary(queryStringKey, queryStringValue));
return request;
}
public static ILogger CreateLogger(LoggerTypes type = LoggerTypes.Null)
{
ILogger logger;
if (type == LoggerTypes.List)
{
logger = new ListLogger();
}
else
{
logger = NullLoggerFactory.Instance.CreateLogger("Null Logger");
}
return logger;
}
}
}
TestFactory
클래스는 다음 멤버를 구현합니다.
Data: 이 속성은 샘플 데이터의 IEnumerable 컬렉션을 반환합니다. 키 값 쌍은 쿼리 문자열로 전달되는 값을 나타냅니다.
CreateDictionary: 이 메서드는 키/값 쌍을 인수로 허용하고 쿼리 문자열 값을 나타내는
QueryCollection
를 만드는 데 사용되는 새Dictionary
를 반환합니다.CreateHttpRequest: 이 메서드는 지정된 쿼리 문자열 매개 변수로 초기화된 HTTP 요청을 만듭니다.
CreateLogger: 로거 형식에 따라 이 메서드는 테스트에 사용되는 로거 클래스를 반환합니다.
ListLogger
는 테스트에서 평가에 사용할 수 있는 기록된 메시지를 추적합니다.
마지막으로 FunctionsTests.cs라는 Functions.Tests 프로젝트에 새 클래스를 만들고 다음 코드를 입력합니다.
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Xunit;
namespace Functions.Tests
{
public class FunctionsTests
{
private readonly ILogger logger = TestFactory.CreateLogger();
[Fact]
public async void Http_trigger_should_return_known_string()
{
var request = TestFactory.CreateHttpRequest("name", "Bill");
var response = (OkObjectResult)await MyHttpTrigger.Run(request, logger);
Assert.Equal("Hello, Bill. This HTTP triggered function executed successfully.", response.Value);
}
[Theory]
[MemberData(nameof(TestFactory.Data), MemberType = typeof(TestFactory))]
public async void Http_trigger_should_return_known_string_from_member_data(string queryStringKey, string queryStringValue)
{
var request = TestFactory.CreateHttpRequest(queryStringKey, queryStringValue);
var response = (OkObjectResult)await MyHttpTrigger.Run(request, logger);
Assert.Equal($"Hello, {queryStringValue}. This HTTP triggered function executed successfully.", response.Value);
}
[Fact]
public void Timer_should_log_message()
{
var logger = (ListLogger)TestFactory.CreateLogger(LoggerTypes.List);
new MyTimerTrigger().Run(null, logger);
var msg = logger.Logs[0];
Assert.Contains("C# Timer trigger function executed at", msg);
}
}
}
이 클래스에 구현된 멤버는 다음과 같습니다.
Http_trigger_should_return_known_string: 이 테스트는 HTTP 함수에 대한
name=Bill
의 쿼리 문자열 값이 포함된 요청을 만들고 예상 응답이 반환되었는지 확인합니다.Http_trigger_should_return_string_from_member_data: 이 테스트는 HTTP 함수에 샘플 데이터를 제공하기 위해 xUnit 특성을 사용합니다.
Timer_should_log_message: 이 테스트는
ListLogger
인스턴스를 만들고 타이머 함수에 전달합니다. 함수가 실행되면 로그를 확인하여 예상 메시지가 있는지 확인합니다.
테스트에서 애플리케이션 설정에 액세스하려는 경우 모의 환경 변수 값을 사용하여 인스턴스를 IConfiguration
함수에 삽입할 수 있습니다.
테스트 실행
테스트를 실행하려면 테스트 탐색기로 이동하여 보기에서 모든 테스트 실행을 선택합니다.
테스트 디버그
테스트를 디버그하려면 테스트에 중단점을 설정하고, 테스트 탐색기로 이동하고, 실행 > 마지막 실행 디버그를 선택합니다.
Visual Studio 2017이 있는 Azure Functions 도구
Azure Functions 도구는 Visual Studio 2017부터 Azure 개발 워크로드에서 사용할 수 있습니다. Visual Studio 2017에서 Azure 개발 워크로드는 Azure Functions 도구를 별도의 확장으로 설치합니다. Visual Studio 2019 이상에서 Azure Functions 도구 확장은 Visual Studio의 일부로 업데이트됩니다.
Visual Studio 2017 설치를 업데이트할 경우 Azure Functions 도구의 최신 버전을 사용하고 있는지 확인합니다. 다음 섹션에서는 Visual Studio 2017에서 Azure Functions 도구 확장을 확인하고 필요한 경우 업데이트하는 방법을 보여 줍니다.
Visual Studio 2017에서 도구 버전 확인
도구 메뉴에서 확장 및 업데이트를 선택합니다. 설치됨>도구를 펼치고 Azure Functions 및 웹 작업 도구를 선택합니다.
설치된 버전을 확인하고 릴리스 정보에 나열된 최신 버전과 지금 설치된 버전을 비교합니다.
최신 버전이 아닌 경우 다음 섹션에 표시된 대로 Visual Studio에서 도구를 업데이트합니다.
Visual Studio에서 도구 업데이트
확장명 및 업데이트 대화 상자에서 업데이트>Visual Studio Marketplace를 확장하고, Azure Functions 및 웹 작업 도구를 선택하고 업데이트를 선택합니다.
도구 업데이트를 다운로드한 후에 닫기를 선택한 다음 Visual Studio를 닫고 VSIX 설치 프로그램을 사용하여 도구 업데이트를 트리거합니다.
VSIX 설치 프로그램에서 수정을 선택하여 도구를 업데이트합니다.
업데이트가 완료되면 닫기를 선택하고 Visual Studio를 다시 시작합니다.
다음 단계
Azure Functions Core 도구에 대한 자세한 내용은 Azure Functions Core 도구로 작업을 참조하세요.
.NET 클래스 라이브러리와 같은 함수를 개발하는 방법에 대한 자세한 내용은 Azure Functions C# 개발자 참조를 참조하세요. 이 문서에서는 특성을 사용하여 Azure Functions에서 지원하는 다양한 유형의 바인딩을 선언하는 방법의 예제로 연결합니다.