Run pod install
and launch Marvel.xcworkspace
Replace in Marvel/API/MarvelApiAuthorization.swift
the value of the constants publicAPIKey
and privateAPIKey
by valid Marvel API keys.
- MVVM is the presentation pattern.
- The
ViewModel
encapsulates business logic by providing pure functions which transform input streams into output streams. This layer uses the power of Rx operators for these transformations, without subscribing to any of its passive streams, ensuring all subscriptions begin and end in theView
layer respecting its lifecycle. Also,errors
are never emitted to theView
, which is ensured in compile-time throughDrivers
. - The
View
subscribes to theViewModel
streams, binding them to UI components. - The network layer is connected to the
ViewModel
throughServices
, which mapData
streams into domain-specific models (using Swift'sJSONDecoder
) Services
on their turn are the connection toRxCocoaNetworking
: they encapsulate aProvider
, which is responsible for firing network requests according to the API specifications. These specs are coded in entities implementingProductionTargetType
orTargetType
- in this repository,MarvelApi
represents such entity.
Unfortunately, a very high coverage (even 100%) does not mean that all possible scenarios have been tested. It does mean, however, that at least for the proposed scenarios, certain blocks of code have been run at least once during unit or UI tests without crashing. That's why I personally like this metric as a great way to detect unused, untestable or potentially unsafe code - nothing else.
With that in mind, this repository is set up with codecov, to which code coverage reports are sent at the end of every successful CI build. codecov
will then reject a commit that has added untested code. That's why you will see "failed" builds (with a ❌ sign) in the list of commits. I have ensured that all reachable paths are at least executed by tests (methods required
by Swift but unavailable
are among the rare unreachable exceptions). This dirty hack was a sacrifice in name of a more trustworthy coverage metric. On the other hand, I have probably missed testing important scenarios.
IMHO, the best way to stay productive and testable is to add only essential tests at first, considering the "happy path" and any other obviously possible paths that come to mind, leaving edge cases to be added once a bug is actually found or whenever a code reviewer suggests something new.
Finally, I like tests as a replacement for embedded documentation. If this were a project following BDD, with technical specifications written in that format by the QA team before reaching the development team, Quick+Nimble would be a great fit. Originally in this project I didn't use it because RxNimble integrated with RxBlocking rather than RxTest - which I consider to be far superior for testing Rx code - but now it does integrate so we can hang out with the cool kids!
This project is still a big work in progress. Crucial details have been left behind, especially from a UI/UX perspective, for example:
- No loading indicators
- No animations
- No images
Please feel free to check this other similar repository where I've invested a little time on the items above, but don't expect anything fancy 😬
My main concern today with the code itself is the existence of test code in the production target, which was done in order to allow network-free UI tests. One of the goals of RxCocoaNetworking
was to keep Moya
's ease of testing while allowing to keep test code out of the production target - that strategy works for unit tests but not for UI tests because we can't add any code there.