Skip to content

Conversation

yjchun626
Copy link
Contributor

개요

구현 내용

1. DeploymentModelListComponent 생성

  • PlaygroundApp 프로젝트 내 'Components/UI'에 UI 컴포넌트 'DeploymentModelListComponent.razor' 파일 생성
  • FluentUI - FluentSelect와 FluentOption을 사용해 컴포넌트 구현
  • 데이터는 FluentOption으로 하드코딩 처리
  • Home.razor에 컴포넌트 추가하여 로컬에서 작동 확인하였습니다.
image

2. 테스트 추가

  • Playwright(통합 테스트)와 BUnit(컴포넌트 단위 테스트)을 이용해 'DeploymentModelListComponentTests.cs' 파일 작성

2-1. Playwright

  • 드롭다운 UI가 포함된 페이지 전체(여기서는 Tests.razor)를 테스트하기 위해 코드를 작성해보았습니다.

2-2. BUnit

  • 기존의 PlaygroundApp 프로젝트를 ProjectReference에 넣어 Components/UI 부분을 직접 참조하는 방식으로 진행했습니다.
  • 현재 (1) 드롭다운 UI가 올바르게 렌더링 되고, 모든 옵션이 잘 표시되는지 확인,
    (2) 옵션 값이 선택되면 ValueChanged 이벤트가 트리거되고, 선택된 값으로 업데이트 되는지 확인
  • 이렇게 총 2개의 테스트 코드를 작성해두었습니다.

잘 모르겠는 점

  • 지금은 UI 컴포넌트 구현에만 집중해서 데이터를 하드코딩 해 놓았는데(FluentOption 단순히 나열), 추후 OpenAPI에서 deployment model을 받아올 것을 생각하고 'DeploymentModelListComponent.razor'에 미리 더 추가하거나 수정해야 할 내용이 있는지 궁금합니다.
  • Playwright와 BUnit으로 테스트를 작성해서 일단 돌려보니 체크 표시가 뜨고 통과는 되었는데, 제가 처음 작성하는 것이다 보니 테스트가 다른 곳에서도 돌릴 수 있게 제대로 짠 것인지 잘 모르겠습니다.
    • 테스트는 README 파일에 추가된 테스트 방법으로 로컬에서 확인하고, 제 fork된 리포지토리에서 workflow가 끝까지 돌아간 것까지 확인했습니다.

justinyoo and others added 20 commits August 18, 2024 12:33
Copy link
Contributor

@justinyoo justinyoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드리뷰 남겼습니다. 중복코드 삭제와 bUnit 사용하지 않는 방향으로 고민해 봐 주세요

Copy link
Contributor

@justinyoo justinyoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

컴포넌트가 자신의 외부로 값을 넘길 때 사용하는 이벤트콜백에 대해 고민을 해 보셔야 합니다.

@justinyoo
Copy link
Contributor

지금 계속 빌드가 깨지는데 로컬에서는 빌드가 잘 돌아가던가요?

@yjchun626
Copy link
Contributor Author

yjchun626 commented Aug 28, 2024

지금 계속 빌드가 깨지는데 로컬에서는 빌드가 잘 돌아가던가요?

일단 제 fork된 레포에서의 빌드는 워크플로우 몇 번 재시도 하다보니 성공이 뜨긴 했습니다...

그런데 지금 상황이 로컬 (vscode에서 './script ...' 실행하는 것을 의미하신 것이 맞나요?) 에서 할때는 다른 것은 다 통과하고 integration test 단계에서 오류가 났다 안 났다 하는 상태입니다.
-> 현재는 로컬에서 잘 돌아가는 상태입니다!!

이번 커밋은 깃헙에 올려보니 계속 Unit test에서 몇개가 fail이 떠서 (fail/success - 2/99, 1/100 이런식으로 랜덤) 계속 확인해봤는데 run 할때마다 매번 다른 것에서 fail이 나더라고요... 자세히 캐치는 못했는데 AppHost 관련된 부분에서 자주 에러가 뜨는 것 같습니다.

Error Message
System.Net.Http.HttpRequestException : An error occurred while sending the request. ---- System.IO.IOException : Unable to read data from the transport connection: Connection reset by peer. -------- System.Net.Sockets.SocketException : Connection reset by peer
  • 결론: 깃헙 액션 여러 번 돌리면 그 중에 한 번 꼴로 success가 뜨는 상태입니다.

@yjchun626
Copy link
Contributor Author

yjchun626 commented Aug 28, 2024

어디다 작성해놔야 좋을지 잘 모르겠어서 일단 기록용으로 코멘트에 작성하겠습니다! (resolved 처리되니까 링크가 안 먹히더라고요)


Blazor 컴포넌트 수명 주기 메소드 조사 배경

혹시 OnAfterRenderAsync() 메소드와 OnInitializeAsync() 메소드의 차이를 알아보고 둘 중 어떤 것이 여기에 적합한지 설명해 주실 수 있나요?

  • 현재 작업 중인 DeploymentModelListComponent.razor 드롭다운 UI 컴포넌트를 자식으로 갖는, Tests.razor 페이지 컴포넌트에서 OnAfterRenderAsync()를 사용하고 난 뒤 피드백을 받게 돼서 조사하게 되었습니다.

결론부터 말씀드리면

  • OnInitializedAsync() 메소드를 사용하는 것이 적합한 것 같습니다.
    • (OnAfterRender는 UI 이벤트가 트리거 된 이후의 프로세스이므로)

이전에 잘못 생각했던 것

  1. OnInitializedAsync() - 컴포넌트 초기화
    • 작업 중인 컴포넌트가 드롭다운 목록이고 정적으로 option을 로드하므로 매개변수 영향이 없음 -> DeploymentModelListComponent.razor에서 사용
  2. OnAfterRenderAsync() - 컴포넌트를 대화형 렌더링 후 업데이트 완료가 된 뒤에 호출
    • 페이지 로드 - 컴포넌트 렌더링하고 나서 1회 수행
  • 코드를 작성할 때 저는 Tests.razor가 @rendermode InteractiveServer 대화형 렌더링 모드를 사용하고 있기 때문에 페이지 초기화 수행을 명시해줘야 할 지 헷갈렸던 것 같습니다.
    (개념 확립하지 않고서 페이지도 결국 컴포넌트인데 그 점을 간과했던 것 같습니다...)
  • 그리고 OnAfterRenderAsync()을 사용함으로써, 앞서 OnInitializedAsync()로 초기화된 UI 컴포넌트를 렌더링 해서 불러오면 이후에 페이지가 잘 받아와서 전체적으로 렌더링 되었는지 최초 확인해주는 메소드라고 생각했습니다.
  • 결론: 완전 헛다리 짚고 있었습니다. (...)

이번에 알게 된 것

image

  • 참고한 글: Component lifecycles - Blazor University, Should I use OnAfterRenderAsync instead of OnInitializedAsync?

  • OnAfterRender는 DOM 이벤트 프로세스의 일부며, 렌더러가 DOM 업데이트 이벤트를 수신함으로써 구동됨

  • ex. 페이지에서 버튼 클릭 등 이벤트 발생 -> OnInitialized 이후에 StateHasChanged 호출되면 렌더링 발생 -> 그제서야 OnAfterRender 발생

  • blazor 컴포넌트의 수명 주기에서 OnInitializedOnAfterRender는 별개의 프로세스고, 특히 OnAfterRender는 언제 실행될지 보장할 수 없으며 일반적으로 JSInterop 작업을 할 때만 사용해야 함

  • 따라서 UI 이벤트 핸들러를 작성하더라도 OnInitialized{Async}/OnParametersSet{Async}에 등록해야 함

    • OnInitialized는 구성 요소가 완전히 로드되면 실행되며, UI의 각 컨트롤이 초기화 이벤트 이후에 발생하므로, 이 이벤트에서 데이터를 구성

조사하다 생긴 궁금증 & 멘토님의 답변

  1. OnInitialized{Async}를 사용할 때 동기/비동기의 차이가 부모-자식 간 초기화 순서 보장 유무라고 이해했는데, 만약 나중에 드롭다운 컴포넌트의 로직(deployment model 선택 시 적용)을 구현할 것을 고려하면 플레이그라운드 페이지를 동기 방식으로 설정하는 것을 염두에 두어야 하는지 궁금합니다.
    • deployment model 선택 시 그 데이터가 플레이그라운드 내에서 타고 타고... chat 할 때 적용되기까지 기다려야 될 것 같다고 생각했습니다.

동기식은 쓰레드 블록킹이고, 비동기식은 쓰레드 논블록킹입니다. 순서 보장하고는 상관 없어요. async/await 만 잘 쓰면 됩니다. 못먹어도 비동기식 고고고!

  1. OnInitialized 메소드를 보통 단일 UI 컴포넌트가 아닌 컴포넌트들을 여러 개 모아놓는 페이지 같은 부모 컴포넌트에 주로 사용하는 것이 맞을까요?
    • 수명 주기 자료들을 찾아보면 대체로 부모 컴포넌트를 예로 든 것이 많고, OnInitialized부터 시작해서 뒤따라오는 메소드가 굉장히 많은데 부모 컴포넌트에서 각 자식 컴포넌트 컨트롤을 전체적으로 관리하기 위해 사용하는 것으로 보여져서 궁금합니다.
    • 다만 OnParametersSet은 부모 컴포넌트에서 자식으로 매개변수를 전달받을 때 매개변수를 설정하는 메소드라고 이해했습니다.
    • 사실 부모-자식 반복해서 쓰다보니 구분이 점점 헷갈리는데(...) 일단 다른 컴포넌트로부터 매개변수나 값을 받아오지 않는 컴포넌트에는 OnInitialized{Async}OnParametersSet{Async}를 사용하지 않아도 되는 것으로 이해하면 될까요?

컴포넌트 초기화에 OnInitializedAsync 메소드를 쓰는 거구요, 각 컴포넌트마다 필요할 때 쓰면 됩니다. 초기화 하는 대상은 여러가지가 있을 수 있겠죠?

Copy link
Contributor

@justinyoo justinyoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주석으로 // given // when // then 한 부분들은 다른 테스트들과 동일하게 // Arrange // Act // Assert로 바꿔주세요.

Copy link
Contributor

@justinyoo justinyoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

거의 다 왔습니다! 몇가지만 클린업 정도로 수정해 보시지요.

@yjchun626 yjchun626 closed this Aug 31, 2024
@yjchun626 yjchun626 force-pushed the feature/172-deployment-model-list branch from 07a052c to 25e9630 Compare August 31, 2024 13:58
Copy link
Contributor

@justinyoo justinyoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR 도중에 갑자기 리베이스를 했는지 포스 푸시가 들어와서 당황했는데, 야튼 몇가지 리뷰 코멘트 남겨뒀습니다.

Copy link
Contributor

@justinyoo justinyoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰 코멘트 남겨뒀습니다.

@justinyoo
Copy link
Contributor

@yjchun626 추가 코멘트를 달아뒀습니다. 거의 다 온 것 같아요!

Copy link
Contributor

@justinyoo justinyoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다! LGTM!

@justinyoo justinyoo merged commit a074158 into aliencube:main Sep 6, 2024
1 check passed
@justinyoo justinyoo mentioned this pull request Sep 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Playground] Component - list of deployment models (UI only)
2 participants