标签: ui-testing

如何开始:使用 AssertJ Swing 测试 Java Swing GUI

在使用 Swing 开发 Java 桌面应用程序时,我遇到了直接测试 UI 的需要,而不仅仅是通过单元测试测试底层控制器/模型类。

这个答案(关于“基于 Swing 的应用程序的最佳测试工具是什么?”)建议使用FEST,不幸的是,它已停止使用。然而,有一些项目是从 FEST 离开的地方继续进行的。特别是一个(在这个答案中提到)引起了我的注意,因为我之前在单元测试中使用过它:AssertJ

显然有AssertJ Swing,它基于 FEST 并提供了一些编写 Swing UI 测试的易于使用的方法。但是,进行初始/工作设置仍然很麻烦,因为很难说从哪里开始。


如何为以下示例 UI 创建最小的测试设置(仅包含两个类)?

约束:Java SE、Swing UI、Maven 项目、JUnit

public class MainApp {

    /**
     * Run me, to use the app yourself.
     *
     * @param args ignored
     */
    public static void main(String[] args) {
        MainApp.showWindow().setSize(600, 600);
    }

    /**
     * Internal standard method to initialize the view, returning the main JFrame (also to be …
Run Code Online (Sandbox Code Playgroud)

java swing ui-testing assertj

5
推荐指数
1
解决办法
7357
查看次数

Flutter Widget测试中,如何将media.orientation设置为纵向?

在构建方法中,MediaQuery.of(context).orientation等于Orientation.landscape. 如何使其成为portrait.

测试小部件被包裹在MaterialApp.

ui-testing flutter

5
推荐指数
1
解决办法
1784
查看次数

使用 Cypress 在 SVG 上测试 onclick 事件

我正在用 Cypress 测试 d3 应用程序。在测试中,我想确保在单击 SVG 元素中的圆圈时调用特定函数。当我手动单击但我编写的测试失败时会调用该函数,因此我认为我在测试中的某个地方犯了错误。这是我现在拥有的测试代码:

import * as app from "../../app";

describe("Scatter plot", () => {
  before(() => {
    cy.visit("http://localhost:1234");
  });
  it("Triggers the displayMovieInfo on click", () => {
    const displayMovieInfo = cy.spy(app, "displayMovieInfo");
    cy.get("#scatterPlot")
      .get("circle")
      .eq(0)
      .click({ force: true });

    expect(displayMovieInfo).to.be.called;
  });
});
Run Code Online (Sandbox Code Playgroud)

我从赛普拉斯得到的输出:

预计 displayMovieInfo 至少被调用过一次,但从未被调用过

任何帮助将不胜感激!

更新:我相信点击之前可能不起作用,因为当柏树尝试点击它时,圆圈不存在。通过添加“等待 cy.wait(1000);” 在单击操作之前,调用该函数(我可以看到结果和从其中记录的消息)。遗憾的是,测试仍然失败。

更新2:我将测试改为使用window对象(见下文),但断言仍然失败(测试本身成功,这也不是一件好事)。

 cy.window()
      .then(window => {
        displayMovieInfoSpy = cy.spy(window, "displayMovieInfo");
        cy.get("#scatterPlot")
          .get("circle")
          .eq(2)
          .click({ force: true })
          .as("clicking");
        expect(displayMovieInfoSpy).to.be.called;
      });
Run Code Online (Sandbox Code Playgroud)

更新3:似乎d3和parcel.js的组合导致测试失败。当单独使用 d3 或单独使用 parcel.js 时,测试工作正常。此外,expect 语句应该在点击动作之后的 then …

javascript testing ui-testing d3.js cypress

5
推荐指数
2
解决办法
3819
查看次数

Selenium C# 如何处理“打开选择一个应用程序”警报?

我正在尝试使用 Selenium C# for Chrome 获取警报文本

在此输入图像描述

但这个警报似乎与普通的 JavaScript 警报不同,使用下面的代码会返回错误异常:

string text = driver.SwitchTo().Alert().Text;
Run Code Online (Sandbox Code Playgroud)

OpenQA.Selenium.NoAlertPresentException:没有这样的警报

这是否被视为警报?有办法处理吗?

c# selenium alert ui-testing selenium-chromedriver

5
推荐指数
1
解决办法
3155
查看次数

在发出获取请求后,编写 Testcafe 测试来断言加载微调器是可见的

我有以下场景:

  • 加载页面
  • 期望微调器是隐藏的
  • 输入用户名点击搜索
  • 期待微调显示
  • 延迟几秒钟后,预计微调器会隐藏
  • 断言显示正确的用户详细信息

这是工作演示 在此处输入图片说明

我在我的测试规范中模拟了网络请求,但我无法理解在单击搜索按钮后如何断言微调器可见

这是我的测试规范:

    import {Selector, RequestMock} from "testcafe";
   import mockUser from "../mocks/mockUser.json";

var apiMocks = RequestMock()
  .onRequestTo(/\/api\/users/)
  .respond(mockUser, 200, {
    'access-control-allow-credentials': "*",
    'access-control-allow-origin': "*"
  })
fixture `When a user is searched`
  .page(`http://localhost:3000/`)
  .requestHooks(apiMocks);

test("Should fetch user details", async t => {
  const spinnerEl = Selector("[data-test-id='spinner']");

  await t.expect(spinnerEl.exists).notOk();

  await t
    .typeText("[data-test-id='txt-search']", "foo")
    .click("[data-test-id='btn-search']");
   // This line does not work
  // await t.expect(spinnerEl.exists).ok();
  await t.expect(Selector("[data-test-id='username']").innerText).eql("Foo Bar");
  await t.expect(Selector("[data-test-id='userid']").innerText).eql("foo");
})
Run Code Online (Sandbox Code Playgroud)

我是 TestCafe 的新手,有人可以帮我解决这个问题。

谢谢!

testing automated-tests ui-testing ui-automation testcafe

5
推荐指数
1
解决办法
515
查看次数

如何通过 UI 测试在 Jetpack compose TextField 中输入文本?

在 Jetpack compose 中,我有一个 TextField,我正在尝试编写 Espresso UI 测试。我没有找到如何在 TextField 中输入文本,请问有什么想法吗?

        TextField(
            value = textState.value,
            modifier = Modifier.fillMaxWidth(),
            onValueChange = {
                textState.value = it
                apiServiceCall(textState.value.text)
            },
            keyboardOptions = KeyboardOptions(capitalization = KeyboardCapitalization.Sentences)
        )

@get:Rule
val composeTestRule = createAndroidComposeRule<MainActivity>()

@Test
fun enterTextAndMakeServiceCall() {
    ActivityScenario.launch(MainActivity::class.java)

    //TODO: Enter text inside the TextField
    composeTestRule.onNode(hasText(getString(R.string.result)))
}
Run Code Online (Sandbox Code Playgroud)

android ui-testing android-espresso android-jetpack android-jetpack-compose

5
推荐指数
1
解决办法
378
查看次数

使用 Cypress 进行 UI 测试,并使用 ADFS 对 Azure AD 进行身份验证

这些是我关于如何使用 MSAL.js 和 ADFS(在我们的示例中是本地部署)以及与令牌创建和本地存储过程关联的架构对 Azure AD 单页应用程序进行 UI 测试的注释。

教程中:“它使用 ROPC 身份验证流程来获取测试用户帐户的令牌,并在运行测试之前将它们注入到浏览器本地存储中。这样,MSAL.js 就不会尝试获取令牌,因为它已将令牌存储在缓存中”。

观看精彩视频后: https://www.youtube.com/watch ?v=OZh5RmCztrU

...并浏览此处的存储库: https://github.com/juunas11/AzureAdUiTestAutomation

我一直试图将本地 ADFS 与 MSAL.js 2.0 和会话存储的使用与上述教程和代码相匹配。因此,如果您使用以/adfs/oauth2/token结尾的 Azure 链接 (而不是 oAuth /oauth2/v2.0/token ),请按照以下步骤操作!

我所做的大部分更改来自 auth.js:https://github.com/juunas11/AzureAdUiTestAutomation/blob/main/UiTestAutomation.Cypress/cypress/support/auth.js

只需按照教程复制该内容,然后更改以下内容:

  • 常量环境='';(我的是公司域名而不是login.windows.net)
  • 对于帐户实体 (const buildAccountEntity) 使用:
    authorityType: 'ADFS', ...并删除行:clientInfo: "",
  • 对于访问令牌实体: (const buildAccessTokenEntity): ...添加行: tokenType: 'bearer',
  • 为刷新令牌(新)实体添加新函数:
    const buildRefreshTokenEntity = (homeAccountId: string, accessToken: string) => {
        return {
            clientId,
            credentialType: 'RefreshToken',
            environment,
            homeAccountId,
            secret: accessToken,
        };
    };
Run Code Online (Sandbox Code Playgroud)
  • 接下来,我必须通过使用 VS Code 在本地运行它并登录来匹配我的 sessionStorage TOKEN,然后对所存储的内容进行逆向工程所需的键值对(结果在下一个代码块中!)。
  • 具体来说,我保留了“家庭帐户”的区分大小写,我删除了一些值,并且必须添加 …

adfs ui-testing azure azure-ad-msal cypress

5
推荐指数
0
解决办法
2898
查看次数

使用协程测试简单的加载+获取流程,就像使用 StandardTestDispatcher 进行 Android 仪器测试一样

我想在 Android 中测试以下非常常见的用例作为仪器测试:

  • 单击按钮时,我的 ViewModel 中会调用 fetch() 函数
  • 该函数告诉视图显示加载覆盖
  • 它在协程中执行提取
  • 获取结果后,它让视图知道显示结果

这是我的 Viewmodel 中的函数:

fun fetch() {
    _loading.value = true //loading is shown
    viewModelScope.launch {
        val results = fetchUseCase() //suspend function
        _result.postValue(results)
        _loading.postValue(false) //loading is not displayed
    }
}
Run Code Online (Sandbox Code Playgroud)

这是根据此 CodeLab https://developer.android.com/codelabs/advanced-android-kotlin-training-testing-survey#4进行的测试:

@HiltAndroidTest
@UninstallModules(CoroutinesDispatcherModule::class)
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTestJunit4Deprecated {

@get:Rule
var hiltRule = HiltAndroidRule(this)

@ExperimentalCoroutinesApi
@get:Rule
var mainCoroutineRule = MainCoroutineRule()

@Before
fun setup() {
    ActivityScenario.launch(HomeScreenActivity::class.java)
}

@ExperimentalCoroutinesApi
@Test
fun fetchTest() {

    //pausing the long running tasks
    mainCoroutineRule.pauseDispatcher()

    //When clicking the …
Run Code Online (Sandbox Code Playgroud)

android ui-testing dispatcher coroutine kotlin

5
推荐指数
0
解决办法
624
查看次数

为什么单元测试不需要 Hilt,但 UI 测试却需要 Hilt?

Hilt 测试指南文档中有一段关于单元测试的内容

Hilt 对于单元测试来说不是必需的,因为在测试使用构造函数注入的类时,您不需要使用 Hilt 来实例化该类。相反,您可以通过传入假或模拟依赖项来直接调用类构造函数,就像构造函数没有注释一样:

@ActivityScoped
class AnalyticsAdapter @Inject constructor(
  private val service: AnalyticsService
) { ... }

class AnalyticsAdapterTest {

  @Test
  fun `Happy path`() {
    // You don't need Hilt to create an instance of AnalyticsAdapter.
    // You can pass a fake or mock AnalyticsService.
    val adapter = AnalyticsAdapter(fakeAnalyticsService)
    assertEquals(...)
  }
}
Run Code Online (Sandbox Code Playgroud)

在这里你可以看到文档正在解释如何在UI测试中使用Hilt。

我的问题是为什么 Hilt 对于单元测试来说不是必需的,但对于 UI 测试却是必需的?

android unit-testing dependency-injection ui-testing dagger-hilt

5
推荐指数
1
解决办法
2391
查看次数

Espresso如何点击listview第一个项目中的ImageView?

我有listview的自定义布局,我想点击列表视图项中的imageview,列表视图中第一项的溢出图标.

我想点击ID为"rcOverflow"的最后一张imageview

我的布局,

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingBottom="10dp"
android:paddingTop="5dp">

<ImageView
    android:id="@+id/rcCircle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignWithParentIfMissing="true"
    android:layout_alignParentTop="true" />

<TextView
    android:id="@+id/rcTime"
    android:layout_width="80dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:gravity="right"
    android:maxLines="1"
    android:textColor="#ffffff"
    android:textSize="13sp" />

<RelativeLayout
    android:id="@+id/rsBubble"
    android:layout_width="280dp"
    android:layout_height="wrap_content"
    android:layout_alignWithParentIfMissing="true"
    android:layout_below="@id/recordsMonthHeader"
    android:paddingBottom="16dp"
    android:paddingTop="16dp">

    <ImageView
        android:id="@+id/rcImage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:layout_alignParentTop="true"
        android:visibility="gone"
        android:layout_marginLeft="3dp"
        android:layout_marginRight="4dp"/>

    <TextView
        android:id="@+id/rcFilename"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft="10dp"
        android:textColor="#000000"
        android:maxLines="2"
        android:ellipsize="end"
        android:textSize="15sp" />

    <TextView
        android:id="@+id/rcDuration"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@id/recordsFilename"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="2dp"
        android:textColor="#a09f9f" />

    <ImageView
        android:id="@+id/records_location_image"
        android:layout_width="12dp"
        android:layout_height="12dp"
        android:layout_alignBottom="@id/recordsDuration"
        android:layout_marginBottom="4dp" />

    <TextView
        android:id="@+id/rcLocation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@id/recordsDuration"
        android:layout_marginBottom="1dp"
        android:layout_marginLeft="3dp" …
Run Code Online (Sandbox Code Playgroud)

android ui-testing junit4 android-testing android-espresso

4
推荐指数
1
解决办法
1240
查看次数