在使用 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) 在构建方法中,MediaQuery.of(context).orientation等于Orientation.landscape. 如何使其成为portrait.
测试小部件被包裹在MaterialApp.
我正在用 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 …
我正在尝试使用 Selenium C# for Chrome 获取警报文本
但这个警报似乎与普通的 JavaScript 警报不同,使用下面的代码会返回错误异常:
string text = driver.SwitchTo().Alert().Text;
Run Code Online (Sandbox Code Playgroud)
OpenQA.Selenium.NoAlertPresentException:没有这样的警报
这是否被视为警报?有办法处理吗?
我有以下场景:
我在我的测试规范中模拟了网络请求,但我无法理解在单击搜索按钮后如何断言微调器可见
这是我的测试规范:
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 的新手,有人可以帮我解决这个问题。
谢谢!
在 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
这些是我关于如何使用 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
只需按照教程复制该内容,然后更改以下内容:
const buildRefreshTokenEntity = (homeAccountId: string, accessToken: string) => {
return {
clientId,
credentialType: 'RefreshToken',
environment,
homeAccountId,
secret: accessToken,
};
};
Run Code Online (Sandbox Code Playgroud)
我想在 Android 中测试以下非常常见的用例作为仪器测试:
这是我的 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)
@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) 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
我有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) ui-testing ×10
android ×4
cypress ×2
testing ×2
adfs ×1
alert ×1
assertj ×1
azure ×1
c# ×1
coroutine ×1
d3.js ×1
dagger-hilt ×1
dispatcher ×1
flutter ×1
java ×1
javascript ×1
junit4 ×1
kotlin ×1
selenium ×1
swing ×1
testcafe ×1
unit-testing ×1