I want to made my first serious side project and start testing from beginning, there is a lot of test types which should I use most? This project will be strongly based on Turbo functionality so I think I should use most system tests with Capybara, I won’t tests views, but I want to use a lot of interactors to put there business logic, should I also test them in isolation, or just green system tests will be fine?
In my experience, you will get the most bang for your buck with capybara system tests, because you will get the most code coverage and assurance ‘for free’, as the whole Rails stack will be exercised (no view typos, etc.)
That being said if you have complex or transactional business logic, I find it useful to put that into its own ‘service’ or other PORO (plain old ruby object) where you can more easily and quickly test happy and sad paths of that particular business case in isolation.
Lastly, down the road, wide system test coverage is a great way to prevent regressions (determining if changes have broken other parts of your application unexpectedly), although they will not be as useful in pointing out specifically what broke, and that is where more specific isolated tests can be useful.
tl;dr my process is generally this:
- Write a system test that expresses the idea of the feature based on how a user will interact with the happy path.
- Attempt to get the system test to pass step by step by adding (usually untested) controllers and (usually tested, with shoulda matchers or something to check validations) models.
- At the end, if needed, refactor with a service or other business object, sometimes with its own test, if it is warranted.
- Adjust the original system test if the understanding of the feature changed while it was being implemented.
Thanks for reply, I also was thinking about it but was not sure if I thought correct, so thanks! Also maybe you can say something about views, How to organize them without too match abstract way for example like view_components, ordinary partials + draper for decorators will be fine?
Draper: I like draper, and I use it, but some people think it is overkill. I think it works great for two use cases: 1) things like
post_subheader that are display concerns that shouldn’t be directly on the model. Sure, those could go directly on the model, if you want. 2) When you want to represent thing X really more like a thing Y (backed by an X). I know that is abstract, but for example if you have a context where you want to represent a
User like a
PostAuthor and other times you want to display them in a
BillingRepresentative context. It may make sense to conditionally wrap the same model by different decorators to handle different user interfaces. Contrived, but sometimes this works. Verdict: start without it until you have an a-ha moment where you need to express complicated view logic on a per-model basis (ideally in more than one place), or you have some shared display logic that you want to reuse for multiple models (I have some decorators that include a common ‘decorator module’).
Partials: Yes, use partials. These will get you 90% of the way there for most cases that might use
ViewComponent. My most common use case for partials is reusing a
_form for both
edit. They also work well for list items, and in some cases layout things, like
_sidebar. Typically the best advice for using partials is to always pass
locals: instead of using
@instance_variables, unless you can be absolutely sure that your
@instance_variable will be in scope everywhere you use the partial (protip: you can’t.) I would also be wary of using
helper_methods that you define in controllers, as those may not always be available in the same way that
@instance_variables won’t. Verdict: use them.
ViewComponent: I sort of like this, and have used it successfully, but it takes some getting used to. And, in my opinion,
ViewComponent isn’t really ‘finished’, in that I think in the future a better implementation will replace it. The place I think this comes into play really is layout concerns. For example, if you can define your applications layout and reusable components with ViewComponent, great (because it decouples your css and markup from high level layout concerns, like what is a sidebar). I find some but limited use for the “my component has complicated display logic and so it should be in ruby not in the view” use case. Mostly I think this can be done in a sane way with partials, but your use case may be complex enough to warrant it. Verdict: honestly you probably don’t need this unless you have a design principles document or something, or you have a really complex SPA-looking application with tons of UI. I don’t think there is really a need for a
BlogPostComponent, you can probably just use views and partials.