{"id":2102,"url":"https://github.com/inkling/Subliminal","last_synced_at":"2025-08-02T23:32:00.704Z","repository":{"id":7705945,"uuid":"9070674","full_name":"inkling/Subliminal","owner":"inkling","description":"An understated approach to iOS integration testing.","archived":false,"fork":false,"pushed_at":"2015-11-12T17:01:04.000Z","size":16435,"stargazers_count":756,"open_issues_count":45,"forks_count":54,"subscribers_count":61,"default_branch":"master","last_synced_at":"2024-09-18T10:51:10.100Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/inkling.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-03-28T05:26:10.000Z","updated_at":"2024-06-13T09:47:42.000Z","dependencies_parsed_at":"2022-09-02T08:50:06.740Z","dependency_job_id":null,"html_url":"https://github.com/inkling/Subliminal","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inkling%2FSubliminal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inkling%2FSubliminal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inkling%2FSubliminal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inkling%2FSubliminal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/inkling","download_url":"https://codeload.github.com/inkling/Subliminal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228503126,"owners_count":17930517,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-01-05T20:16:03.576Z","updated_at":"2024-12-06T17:30:44.004Z","avatar_url":"https://github.com/inkling.png","language":"Objective-C","funding_links":[],"categories":["Testing","测试"],"sub_categories":["UI Testing","Other free courses"],"readme":"\u003cp align=\"center\" \u003e\n  \u003cimg src=\"http://inkling.github.io/Subliminal/readme-images/subliminal-hero.png\" alt=\"Subliminal\" title=\"Subliminal\"\u003e\n\u003c/p\u003e\n\n[![Build Status](https://travis-ci.org/inkling/Subliminal.svg?branch=master)](https://travis-ci.org/inkling/Subliminal)\n[![Gitter chat](https://badges.gitter.im/inkling/Subliminal.png)](https://gitter.im/inkling/Subliminal)\n\nSubliminal is a framework for writing iOS integration tests. Subliminal provides \na familiar OCUnit/XCTest-like interface to Apple's UIAutomation framework, \nwith tests written entirely in Objective-C. Subliminal also provides a powerful \nmechanism for your tests to manipulate your application directly.\n\n[\n[Features](#features) \u0026bull; \n[Getting Started](#how-to-get-started) \u0026bull; \n[Requirements](#requirements) \u0026bull; \n[Usage](#usage) \u0026bull; \n[Continuous Integration](#continuous-integration) \u0026bull; \n[Contributing](#contributing) \u0026bull; \n[Contact](#contact) \u0026bull; \n[License](#copyright-and-license) \n]\n\nFeatures\n--------\n\n#### Seamless Integration\n\nWrite your tests in Objective-C, and run them from Xcode. See rich-text logs \nand screenshots in Instruments. Use UIAutomation to simulate user interaction. \nSubliminal lets you use familiar tools, no dependencies required.\n\n#### Full Control\n\nBy using UIAutomation, Subliminal can simulate almost any interaction--without \nresorting to private APIs. From navigating in-app purchase dialogs, to putting \nyour app to sleep, Subliminal lets you simulate complex interaction like a user. \nAnd when you want to manipulate your app directly, Subliminal will help you do \nthat too.\n\n#### Scalable Tests\n\nDefine Objective-C methods to help set up and tear down tests. Leverage native \nsupport for continuous integration. Take confidence in Subliminal's complete \ndocumentation and full test coverage. Subliminal is the perfect foundation \nfor your tests.\n\nHow to Get Started\n------------------\n\n* [Download Subliminal](https://github.com/inkling/Subliminal/zipball/master) \nand [try out the included example app](#running-the-example-app)\n* See an [installation walkthrough and screencast](https://github.com/inkling/Subliminal/wiki#installing-subliminal)\n* Check out Subliminal's [API documentation](http://inkling.github.io/Subliminal/Documentation/)\nor the [guides to using Subliminal on the Wiki](https://github.com/inkling/Subliminal/wiki#documentation)\n* Read a [comparison of Subliminal to other integration test frameworks](#comparison-to-other-integration-test-frameworks)\n\nRunning the Example App\n-----------------------\n\n1. Clone the Subliminal repo: `git clone https://github.com/inkling/Subliminal.git`.\n2. `cd` into the directory: `cd Subliminal`.\n3. If you haven't already, set up Subliminal: `rake install`.\n4. Open the Example project: `open Example/SubliminalTest.xcodeproj`.\n5. Switch to the \"Integration Tests\" scheme.\n You may also see a scheme called \"Subliminal Integration tests\"--make sure you choose \"Integration Tests.\"\n6. Choose Product \u003e Profile (⌘+I).\n7. Under the User Templates, choose Subliminal.\n\nInstalling Subliminal\n---------------------\n\nFor an installation walkthrough, refer to [Subliminal's wiki](https://github.com/inkling/Subliminal/wiki).\n\nRequirements\n------------\n\nSubliminal supports projects built using Xcode 5.1 and iOS 7.x SDKs,\nand deployment targets running iOS 6.1 through 7.1.\n\nFor iOS 5.1 support, use Subliminal 1.1.0 (found in the\n[Releases](https://github.com/inkling/Subliminal/releases/) section or on\n[CocoaPods](http://cocoapods.org/)). To test in the iOS 5.1 Simulator, you will\nneed to run OS X 10.8 and manually add the iOS 5.1 Simulator to Xcode 5.1,\nas described [here](http://stackoverflow.com/a/22494536/495611).\n\nUsage\n-----\n\nSubliminal is designed to be instantly familiar to users of OCUnit/XCTest. \nIn Subliminal, subclasses of `SLTest` define tests as methods beginning with `test`. \nAt run-time, Subliminal discovers and runs these tests. \n\nTests manipulate the user interface and can even [manipulate the application directly](https://github.com/inkling/Subliminal/wiki/Writing-Tests#manipulate-the-application-directly).\nHere's what a sample test case looks like:\n\n```objc\n@implementation STLoginTest\n\n- (void)testLogInSucceedsWithUsernameAndPassword {\n\tSLTextField *usernameField = [SLTextField elementWithAccessibilityLabel:@\"username field\"];\n\tSLTextField *passwordField = [SLTextField elementWithAccessibilityLabel:@\"password field\" isSecure:YES];\n\tSLElement *submitButton = [SLElement elementWithAccessibilityLabel:@\"Submit\"];\n\tSLElement *loginSpinner = [SLElement elementWithAccessibilityLabel:@\"Logging in...\"];\n\t\n    NSString *username = @\"Jeff\", *password = @\"foo\";\n    [usernameField setText:username];\n    [passwordField setText:password];\n\n    [submitButton tap];\n\n\t// wait for the login spinner to disappear\n    SLAssertTrueWithTimeout([loginSpinner isInvalidOrInvisible], \n    \t\t\t\t\t\t3.0, @\"Log-in was not successful.\");\n\n    NSString *successMessage = [NSString stringWithFormat:@\"Hello, %@!\", username];\n    SLAssertTrue([[SLElement elementWithAccessibilityLabel:successMessage] isValid], \n    \t\t\t@\"Log-in did not succeed.\");\n    \n    // Check the internal state of the app.\t\t\t\n    SLAssertTrue(SLAskAppYesNo(isUserLoggedIn), @\"User is not logged in.\")\n}\n\n@end\n```\n\nFor more information, see [Subliminal's wiki](https://github.com/inkling/Subliminal/wiki/Writing-Tests).\n\nContinuous Integration\n----------------------\n\nSubliminal includes end-to-end CI support for building your project, running its tests on the appropriate simulator or device, and outputting results in a variety of formats.\n\nFor example scripts and guides to integrate with popular CI services like Travis and Jenkins, see [Subliminal's wiki](https://github.com/inkling/Subliminal/wiki/Continuous-Integration).\n\n\nComparison to Other Integration Test Frameworks\n-----------------------------------------------\n\n* \t**How is Subliminal different from other integration test frameworks?**\n\n\tMost other integration test frameworks fall into two categories: entirely \n\tObjective-C based, or entirely UIAutomation-based.\n\n\tFrameworks that are entirely Objective-C based, like [KIF](https://github.com/square/KIF/), \n\t[Frank](https://github.com/moredip/Frank), etc., must hack the application's \n\ttouch-handling system, using private APIs, to simulate user interaction. \n\tThere is thus no guarantee that they accurately simulate a user's input. \n\tMoreover, these frameworks can only simulate interaction with the application, \n\tas opposed to interaction with the device, other processes like in-app purchase \n\talerts, etc.\n\n\tFrameworks that are entirely based on Apple's UIAutomation framework require \n\tcumbersome workflows--writing tests in JavaScript, in Instruments--which do not \n\tmake use of the developer's existing toolchain. Moreover, they offer the developer \n\tno means of manipulating the application directly--it is a complete black box \n\tto a UIAutomation-based test.\n\n\tOnly Subliminal combines the convenience of writing tests in Objective-C \n\twith the power of UIAutomation.\n\n* \t**How is Subliminal different than UIAutomation?**\n\n\tBesides the limitations of UIAutomation described above, it is extremely \n\tdifficult to write UIAutomation tests. This is because UIAutomation requires \n\tthat user interface elements be identified by their position within the \n\t[\"element hierarchy\"](https://developer.apple.com/library/ios/#documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/UsingtheAutomationInstrument/UsingtheAutomationInstrument.html#//apple_ref/doc/uid/TP40004652-CH20-SW88), like\n\n\t```js\n\tvar cell = UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[\"foo\"];\n\t```\n\n\tThese references are not only difficult to read but are also difficult to write.\n\tTo refer to any particular element, you have to describe its entire ancestry, \n\twhile including only the views that UIAutomation deems necessary (images, yes; \n\taccessible elements, maybe; private `UIWebView` subviews, sure!).\n\n\tUIAutomation-based tests are not meant to be written, but to be \"recorded\" \n\tusing Instruments. This forces dependence on Instruments, and makes the tests \n\tdifficult to modify thereafter.\n\n\tSubliminal allows developers to identify elements by their properties, \n\tindependent of their position in the element hierarchy:\n\n    ```objc\n    SLElement *fooCell = [SLElement elementWithAccessibilityLabel:@\"foo\"];\n    ```\n\n    Subliminal abstracts away the complexity of UIAutomation scripts to let developers focus on writing tests.\n\n    Subliminal also fixes several bugs in UIAutomation and the `instruments` CLI tool,\n    such as `instruments`' lack for [true device support](https://github.com/inkling/Subliminal/pull/75).\n    And, last but not least, Subliminal rewrites `instruments`' output using human-friendly formatting\n    and ANSI colors:\n\n    ![](http://inkling.github.io/Subliminal/readme-images/PrettyCI.png)\n\n\nContributing\n------------\n\nSubliminal welcomes pull requests! Check out the [contributing guidelines](https://github.com/inkling/Subliminal/blob/master/CONTRIBUTING.md) to learn how to set up Subliminal for development and how to make a successful pull request.\n\nCredits\n-------\n\nCreated by [Jeff Wear](https://github.com/wearhere), made possible by [Inkling](https://www.inkling.com/), \nwith help from:\n\n* [William Green](http://ca.linkedin.com/pub/william-green/21/724/105)\n* [John Detloff](https://github.com/jmdetloff)\n* [Aaron Golden](http://stackoverflow.com/users/2172667/aaron-golden)\n* [Lukhnos Liu](https://github.com/lukhnos)\n* [Aaron Haney](https://github.com/ahaneyinkling)\n\nand Subliminal's [growing list of contributors](https://github.com/inkling/Subliminal/contributors).\n\nContact\n-------\n\n* If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/subliminal). (Tag 'subliminal'.)\n* If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/subliminal).\n* If you've **found a bug**, [open an issue](https://github.com/inkling/Subliminal/issues/new).\n* If you **have a feature request**, [open an issue](https://github.com/inkling/Subliminal/issues/new).\n* If you'd **like to contribute** (awesome!), see [the contributing guidelines](https://github.com/inkling/Subliminal/blob/master/CONTRIBUTING.md) to get started.\n\nIf you'd like to chat, we hold \"office hours\" on [Gitter](https://gitter.im/inkling/Subliminal)\n3-4pm Pacific Time, Tuesdays and Thursdays.\n\nLastly, you can follow Subliminal on Twitter for news and tips ([@subliminaltest](https://twitter.com/subliminaltest)).\n\nCopyright and License\n---------------------\n\nCopyright 2013-2014 Inkling Systems, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finkling%2FSubliminal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finkling%2FSubliminal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finkling%2FSubliminal/lists"}