Can iOS unit tests be run in milliseconds rather than seconds? - ios

I've been trying quite hard in the past 1.5 years to adopt a test-first process with my iOS development and basically found that two things prohibit me from doing this effectively:
compilation time — as project sources and test sources both grow (i.e. # source files grows), compilation time grows
wait for the iOS Simulator to launch — this can be slow as well.
As a result, even if your tests take milliseconds to run, it could take upwards of 5-10s to get feedback from them, simply because there's that magnitude of time spent preparing those tests to be run.
How can this be mitigated?

Related

React Native - Improve cold start time

The project I was working is to use react native to create an iOS app.
Following is the cold start time in iPhone 5S release build
Pre-main time: 0.52 seconds
App did launch to javascript did load time: 2.12 seconds
JS render time: 0.74 seconds
Total time: 3.34 seconds
The slowest part is to wait react library to load the js bundle (2.2MB). Is the loading time looks normal? How can I improve the js bundle loading time? Thanks so much.
Reducing the js bundle size can improve the time from Application did launch to javascript did load. For a new Hello World project, it only took 0.18-0.19 seconds (iPhone 5S).
Yes, the problem that you described really exist. As a possible solution you can use ram-bundle format, that metro bundler provides.
In this case you will not load the entire js-bundle - you will load only part, that you need at a startup (in a lot of application are a lot of places, which user may not even see, and this feature allow you load such parts, only when they are required). So you can simplify your entry point and load only small piece of your bundle.
You can look at react-native-bundle-splitter. This library well integrated with almost all popular navigation libraries and allows you to postpone a loading of specific routes. For example, if you have a login screen, you can load at start up only this screen, and all others load in background or start the loading of them, only when user can see them. And the startup time of your complex application will be almost equally as for "Hello world" application.
Whether the time ok is up to you and your app users only =)
Obviously, if reducing the js bundle size improves the time, you should do your best to get it done. There is several steps I guess can help you:
first of all, DRY: doubling code do increase the size
check for using npm packages, remove unused (also as unused inner modules)
obfuscate and minify the bundle with third-party tools
Also it should be done to reduce initializing complexity
check an asymptotic complexity of your algorithms - is can cause to time increasing
remove unused variables, functions and data - it can be a reason of redundant memory usage
And I can just advice you also try to affect not only an actual time but also a time feeling. For example, use an animated splash screen

How can consistent initial processing times be obtained on builds uploaded to the App Store?

When I am uploading new builds to the App Store, the processing times for new builds do not seem to be consistent. What I mean is that a build can go through processing quickly as in a matter of minutes and sometimes they seem to get stuck for hours or more. Needless to say, this interferes with my ability to readily use new builds for testing or for submitting them for review.
My question is, is there anything that can be done with regard to the packaging of my IPA or my build settings to obtain more consistent processing times on the App Store?
Please note that I am asking about the initial processing of an uploaded binary and not the time it takes for Apple to review an app.
I’m primarily uploading apps that use both Swift and Objective-C so the Swift runtime libraries are being included in my App Store package. I’m either submitting builds using Xcode 7.0.1 or a custom build script based on xcodebuild. Both methods have successfully uploaded builds but as I stated, the processing times can be wildly irregular and prompts me to reconsider how I am submitting my IPAs.
I want to note that this irregularity can occur at seemingly any time of the day so I’m not sure if that could be a factor.
From casual observation, it seems that newer builds will take priority over older builds. So if you have one build that has not completed processing, the newer build can finish processing before the older one. If a series of builds has been uploaded, the intermediate builds can be stalled for seemingly extended periods of time. This seems like a sensible approach in that more recent builds would have a higher priority in processing. I’m not entirely sure this is happening.
From the experiences of other people having this problem and based on my own observations, I’ve concluded that it is possible for a build to get stuck in the Processing state, sometimes indefinitely. Since Apple does not provide additional information related to this condition, the solution to get more consistent processing times is to submit a new build if a build gets stuck at Processing. Whether or not this is a sure-fire method of affecting the actual processing time is yet to be proven by hard evidence.
This question is open-ended.
App store review times vary wildly and even current time is not a reliable indicator of time if you submit now, but as a guide.
Useful utility here

iOS Instruments : Timer's time is not matching with the sum of running times in call tree

I am analysing an app's slow performance using iOS Instruments. To load a login page it takes around 25 seconds. In Instruments, the timer shows 25 seconds to load the page. But when I sum the running times of the call tree, It is just around 4 seconds only. I want to know where the slowness is occuring. Is there anyway to force instruments to show all the time taken in call tree?
Note: I tried Xamarin profiler also. It shows maximum time taken by any call as 1E-06 ms. Is there any way to know the time taken by the whole method?
Have you considered using the Stopwatch class? It is supported in Project Core Libraries and can be used in a high-resolution mode for higher accuracy. It would allow you to time the execution of a particular method (which sounds like what you are attempting to accomplish). You can find Microsoft documentation and examples here.

Rerunning spec x times if if fails

We have some feature specs which fails randomly. We don't have too much time to fix them and we don't really know for now how to do this. Because of that we must rerun builds on cicrcle ci until they are green. Is it possible to run some spec, and if it fails rerun this few times, until it's green?
Try to have a look at following gems:
https://github.com/dblock/rspec-rerun
https://github.com/y310/rspec-retry
(taken from discussion in https://github.com/rspec/rspec-core/issues/456)
Personally I think having flickering tests is worse then having no tests in the first place because the are adding hassle and they destroy the trust in tests in general, which you need for swift refactoring.
Best would be
delete them since they don't provide the value they should
take your time to rewrite them
For getting the time to do so try to convince management that the investment in time on fixing these issues saves a lot of developer time in the long run (best with quick example calculation: x fails a day, result in yyy extra minutes with devs waiting for the built to be green) ;)

Is MobileServiceSQLiteStore.DefineTable<T> necessary on every run and if so why?

I'm trying to improve app launch performance for subsequent logins (every login after the first) with my mobile app and after putting some stop watch diagnostics I can see that defining my 8 tables with MobileServiceSQLiteStore.DefineTable<T> takes on average 2.5 seconds. Every time.
On an iPhone 4 running iOS 7 the loading time would be less than a second if it weren't for having to define these tables every time. I would expect them to only need to be defined the first run of the app when the SQLite database is setup. I've tried removing the definitions on subsequent logins and try to just get the sync tables but it fails with "Table is not defined".
So, it seems this is the intended behavior. Can you explain why they need to be defined each time and/or if there is any workaround for this? It could be negligible considering my phone is pretty old now.. but it still is something I would like to remove if possible.
Yes, it is required to be called every time because SDK uses it to know how to deserialize data if you read it via untyped interface i.e. IMobileServiceSyncTable instead of IMobileServiceSyncTable<T>.
As of now there is no work around to avoid calling it each time. I'm surprised however that it is taking 2.5 seconds for you because DefineTable does not do any database operations. It merely inspects the members on your type/JObject and maintains an in memory dictionary for later re-use.
I would recommend you to download and compile the SDK and debug your way through to figure out where the time is actually spent.

Resources