Tag: 模拟

iOS:使用Alamofire + Kakapo在Swift中模拟服务器行为和响应

在Tiendeo Mobile部门,我们一直在寻找新的方法来使我们的应用程序更具可测试性和更好的测试。 让我介绍有关数据层的基本概念。 如果您熟悉Alamofire和AlamofireObjectMapper,则我们的应用程序数据层将使用一个名为AuthenticationSessionManager的自定义Alamofire SessionManager类,该类可实现RequestAdapter和RequestRetrier协议。 我们的AuthenticationSessionManager有自己的请求方法,可以在调用Alamofire请求方法之前检查用户令牌是否有效: 首先,我们创建一个称为AuthenticationSessionManagerTest的单元测试测试类,并实现一个方法,该方法返回无效令牌,并使用Kakapo的Router类实现另外两个方法来设置拦截器,用于两个成功的API调用: 然后,我们需要配置我们的自定义SessionManager以使用Kakapo协议。 我们将创建一个方法来创建自定义URLSessionConfiguration : 并且…我们已经完成了测试的// Given部分: 总结一下:我们已经有一个配置有Kakapo和无效令牌的sessionManager 。 我们还有两个API调用可供拦截。 💪 现在我们必须实现测试的// When和// Then部分。 我们将使用sessionManager向“ _api / Fake”发出请求,该请求将被拦截。 正如我们在文章开头所看到的sessionManager , sessionManager将首先检查令牌,但是令牌将无效…… sessionManager自动向“ _api / TokenNew”请求新的令牌,该令牌也将被拦截。 当获得新令牌时,最终它将调用“ _api / Fake” ,其响应将成功。 🎊 让我们看一下代码: 这是测试的样子! 我们使用expectation来检查响应的值是否与我们为Kakapo路由器设置的值相同。 从这里开始 以此测试为样本,我们可以创建多个测试方案来测试我们的SessionManager,如下所示: 有效令牌 伪API调用成功 要么: 没有令牌 刷新令牌API调用成功 伪API调用成功 要么: 有效令牌 伪API调用响应401 等等 只是改变 //给出条件并向Kakapo的路由器添加新的响应。 希望您发现这篇文章有趣并且对您的项目有用。 任何问题或评论都将受到欢迎! […]

Xcode中的位置模拟

假设您的客户在另一个国家,并且应用程序应该使用位置服务,那么唯一的方法就是模拟位置。 Apple使我们能够在应用程序中模拟位置。 该仿真对设备和仿真器均适用。 要模拟位置,请转到目标 → 编辑方案。 然后在“ 运行”方案下,选择“ 选项”选项卡。 如下图所示,应该启用“ 允许位置模拟”复选框。 然后,您可以从下拉菜单中选择默认位置。 现在,连接设备,然后构建并运行该应用程序(在模拟器中也可以相同的方式工作。)。 假设您从下拉列表中选择了印度孟买,则该应用程序实际上在印度。 调用定位方法后,CLLocationManager将返回您印度孟买的位置。 假设您要模拟位置的国家/地区不在下拉列表中,则可以使用一些在线网站创建一个.gpx文件(GPS交换格式),并将其添加到Xcode中(只是Google如何创建gpx文件) )。 您可以在上图的下拉列表底部看到“ 将GPX文件添加到项目中”选项。 要创建GPX文件,您可以转到 http://gpx-poi.com/并只需填写所需数据。 您不必添加所有与gps相关的数据。 我只希望国家代码为VN ,名称为越南。 因此,添加这两个字段→创建→下载。 注意 :也可以在xcode中创建.gpx文件。 转到文件 → newfile,然后选择gpx文件。 这只是一个包含键和值的xml文件。 只需添加名称,符号(用于国家符号)等标签即可。 xml标记示例(用于国家/地区符号): VN 将GPX文件添加到xcode,现在,您可以在列表中看到新添加的位置名称。 在您的应用程序委托应用程序中放置一个断点:didFinishLaunchingWithOptions:。 运行应用程序,并触发断点时,您将在调试区域的跳转栏中看到“定位服务”图标。 选择您的位置,然后运行该应用程序,位置服务现在将在GPX文件中的模拟位置中运行。 重要说明:在设备上模拟位置时,位置服务已被劫持,直到您在关闭位置模拟的情况下部署应用程序为止。 否则,设备中的所有应用程序实际上都将位于模拟位置。 玩得开心 。 模拟愉快! 如果您喜欢阅读这篇文章,请分享并推荐它,以便其他人可以找到💚💚💚💚💚💚!!!!

Swift中的模拟网络层—第3部分

通过模拟URLProtocol 请检查有关网络层第1部分和第2部分的先前文章。 什么是模拟? 在面向对象的编程中,模拟对象是模拟对象,它们以受控方式模拟实际对象的行为。 ( 维基 ) 在我们的例子中,我们必须模仿URLSession,以便它可以返回模拟对象而不会触及物理服务器。 我们可以通过创建对URLProtocol进行确认的MockURLProtocol并实现其所需的方法来实现此目的 。 现在,我们的MockURLProtocol能够处理指定的请求。 现在,我们必须将MockURLProtocol添加到 URLSessionConfiguration.protocolClasses数组以处理会话中的请求。 模拟行动: 例如,要模拟loginUser函数,我们必须准备一个假的响应对象 ,该对象在真实的服务器调用中是我们期望的。 该响应对象将作为MockURLProtocol的 requestHandler的响应返回。 最终的模拟登录用户函数如下所示。 请检查示例代码中的APIMockingTests.swift文件。

Swift中的单元和集成测试技术

单元测试 :是软件测试的级别,其中测试软件的各个单元组件。 目的是验证软件的每个单元是否按设计执行。 集成测试 :是一个软件测试级别,其中各个单元组合在一起并作为一组进行测试 。 此测试级别的目的是暴露集成单元之间交互中的错误。 测试网络请求 让我们看一个示例,该示例显示了使用UrlSession简单网络请求,如图1所示。 这些是我们在此代码中执行的任务 创建一个URL以获取资源 使用默认configuration创建一个dataTask对象 解码从服务器获取的响应 图2显示了符合Codable协议的响应模型struct ,否则.decode将引发error 如上图1所示,我们有三个任务单元。 通过将这两种方法组合在一起,我删除了此代码的可测试性。 我们可以打破这些任务,如图3所示 首先,我们将url请求创建逻辑分离到单独的单元,以便可以分别测试 其次,我们将解析逻辑分离到一个单元,以便该单元可以独立测试 单元测试请求的创建和解析 在这里,我们仅通过制作示例并放入url,将其传递到方法中,并对其返回值进行断言来测试makeRequest方法。 同样,我们可以通过传递一些模拟JSON并对所解析的结果进行断言来测试响应解析。 为了避免do catch块,我们使用了XCTest throws功能 集成测试网络电话 在进行任何集成测试之前,我们首先使逻辑通用。 正如我们所看到的,我们的网络api类仅特定于一个url,并且我们可以使用通用功能来消耗任何种类的url和响应负载 如您在图5中看到的,我们创建了一个APIRequest协议 如图6所示,我们创建了使用请求类型和urlSession实例初始化的APIRequestLoader类。 由于apiRequest应该符合APIRequest协议,因此我们可以访问makeRequest和parseResponse方法。 如图7所示, GitHubRequest实现了APIRequest协议的APIRequest和parseResponse方法,我们将RequestDataType为String并将ResponseDataType设置为MyGitHub类型 如图8所示,我们正在使用通用api函数。 如果将其与图1进行比较,将会看到不同之处。 URLSessionDataTask集成测试 如图9所示,我们通过按正常调用方式调用loadAPIRequest方法来测试它,并等待返回结果,但这两者都要求我们的测试必须通过Internet连接运行 我们需要使加载程序类使用伪造的urlSession ,该伪造的urlSession返回一些模拟数据,而不是访问服务器,这也可以提高测试执行urlSession 。 所以问题是我们如何制作假的或模拟的服务器 使用URLProtocol模拟 URLSession为应用程序提供了高级API,以用于执行网络请求。 表示正在进行的请求的对象,例如URLSession数据测试。 不过,在幕后,还有另一个较低级别的API URLProtocol ,它执行打开网络连接,编写请求以及回读响应的基础工作。 URLProtocol旨在进行子类化,从而为URL加载系统提供扩展点。 Foundation为HTTPS等常见协议提供了内置协议子类,但是我们可以在测试中通过提供一个模拟协议来覆盖这些子类,该协议可以让我们对即将出现的请求进行断言并提供模拟响应。 URLProtocol通过URLProtocolClient协议将进度传达回系统。 如图10所示,我们使requestHandler成为静态属性。 我们在此物业网络中提供的内容将作为响应返回。 当我们调用resume方法时, startloading函数将调用,而不是去服务器,它立即返回requestHandler响应。 […]