能否测试返回Accessibility.Styled.Html的Elm视图函数?
如何测试返回Accessibility.Styled.Html的Elm视图?
问题场景
你在测试Elm应用时,视图函数使用Accessibility.Styled替代了标准Html模块,编写视图测试时使用Html.Test出现类型不匹配错误。
视图模块代码
import Accessibility.Styled as Html exposing (Html) import Css exposing (..) import Http import Nri.Ui.Button.V10 as Button import Nri.Ui.Container.V2 as Container import Nri.Ui.Heading.V2 as Heading import Nri.Ui.TextInput.V7 as TextInput import Session as Session exposing (getSession) type alias Model = { apiBaseUrl : String , email : String , password : String , showPassword : Bool , error : Maybe Http.Error , processing : Bool } type Msg = Email String | Password String | SetShowPassword Bool | SubmittedForm view : Model -> Html Msg view model = Container.view [ Container.css [ width (pct 33), margin auto ] , Container.html [ Heading.h3 [ Heading.css [ marginBottom (px 20) ] ] [ Html.text "Prijava korisnika" ] , TextInput.view "Email" [ TextInput.email Email, TextInput.value model.email ] , TextInput.view "Password" [ TextInput.currentPassword { onInput = Password, showPassword = model.showPassword, setShowPassword = SetShowPassword }, TextInput.value model.password ] , Button.button "Log in" [ Button.primary , Button.onClick SubmittedForm , Button.css [ marginTop (px 20) ] ] ] ]
测试代码
module LoginPageTests exposing (updateTests, updateErrorTests) import Expect exposing (Expectation, err) import Fuzz exposing (Fuzzer, string, bool) import Test exposing (..) import FuzzerHelper exposing (httpErrorFuzzer) import LoginPage exposing (Msg(..), Model, update, updateError) import Test.Html.Query as Query import Test.Html.Selector exposing (attribute, tag, text) viewTests = [fuzz loginModelFuzzer "check view function" <| \model -> model |> LoginPage.view |> Query.fromHtml |> Query.find [tag "btn"] |> Query.count (Expect.equal 1) ]
错误信息
TYPE MISMATCH - This function cannot handle the argument sent through the (|>) pipe: 13| model 14| |> LoginPage.view 15| |> Query.fromHtml #^^^^^^^^^^^^^^# The argument is: #Accessibility.Styled.Html Msg# But (|>) is piping it to a function that expects: #Html.Html msg#Elm
解决方案
1. 转换Styled Html为标准Html
Accessibility.Styled.Html是带样式信息的虚拟DOM类型,而Query.fromHtml只接受标准的Html.Html类型。你可以用Accessibility.Styled.toUnstyled方法将其转换为标准Html:
- 首先在测试模块中导入
Accessibility.Styled:import Accessibility.Styled as StyledHtml - 修改测试代码中的管道:
model |> LoginPage.view |> StyledHtml.toUnstyled -- 添加这一行完成类型转换 |> Query.fromHtml
2. 修正选择器
原测试中的tag "btn"是错误的,NRI的Button组件最终渲染为标准的<button>标签,需要把选择器改成tag "button",还可以结合文本内容更精准定位元素:
修改后的完整测试代码:
viewTests = [ fuzz loginModelFuzzer "视图应渲染一个登录按钮" <| \model -> model |> LoginPage.view |> StyledHtml.toUnstyled |> Query.fromHtml |> Query.find [tag "button", text "Log in"] |> Query.count (Expect.equal 1) ]
3. 关于样式测试的提示
Html.Test主要用于测试DOM结构、文本内容和交互逻辑。如果需要验证样式效果,通常建议在E2E测试(比如用Cypress)中完成,或者检查Accessibility.Styled生成的CSS类名是否存在,但这部分不是单元测试的重点。
内容的提问来源于stack exchange,提问作者a12345
相关产品推荐
相关产品推荐

