On 08/15/2018 03:47 PM, Stefan Hundhammer wrote:
While working on a bug related to the partitions_proposal client of y-storage-ng, I wondered why we don't have a simple way to call our own code.
I want to be able to start the stuff that I work on in my normal work environment.
I was told that "it just takes 4-5 lines of Ruby code", but that's not a useful answer; why don't we have a ready-made wrapper for those things if it's really so simple?
I guess because the exact 4-5 lines depend of what you want to run/test. With modern code, hopefully in all cases running a component (a proposal client, an installation step, a dialog, etc.) is just a matter of instantiating an object of the corresponding class (the dialog, the client, whatever) and running the offending method (typically #run for clients and dialogs). So the basis is always: ``` require "yast" require "y2whatever/dialogs/foo" # Assuming the constructor needs no arguments dialog = Y2Whatever::Dialogs::Foo.new dialog.run ``` There is nothing special (or super useful) there.
I have no clue what I need to set up first before I can call that thing programatically.
And that's the real problem... which I don't see how to solve in a generic way. In order to debug a concrete bug, maybe Dialogs::Foo needs some other YaST module to be previously initialized with some specific value. Or it needs to receive a particular value as constructor argument... It really depends on what you need to reproduce and what Foo expects.
I need to see it in connection with the proposal because that's what it's used for.
We have a lot of infrastructure already in place:
- For storage scenarios, we have YAML files describing the existing disk setup; we use them in the unit tests.
- We have control XML files for all our products.
- We have a lot of AutoYaST files that we use for automated tests.
- We have an examples/ subdirectory in y-storage-ng, but that doesn't contain much.
It's a PITA to start a real installation and then modify the inst-sys with bind-mounts and whatnot, always copying files to that inst-sys after each change.
The easier we make it to call our code directly, the more it will be done which means much more thorough (manual!) testing, and the easier it will be to develop on that code.
Fully agreed. I just do the inst-sys thingy at the end, to verify. For development I usually start writing a RSpec test to reproduce the situation or write a script similar to the one at the start of this mail... and then I use a lot byebug. :-)
Automated testing can only go so far; unit tests use a lot of mocking and assumptions, and OpenQA is limited in the number of scenarios that can reasonably be tested, and it isn't helpful for us during development: I need to see what I am doing, I can't wait for half a week for a test result, and I don't want to check in code that I never saw running (which for Ruby typically means that there will be one crash for every 3 lines of code written).
So, for simple things I propose we get into the habit of providing a simple example that can easily be called. Back when I wrote the UI, I did that for every single widget, and even in different degrees of difficulty and complexity: PushButton1.rb, PushButton2.rb, ...
This encourages people to execute the code, to see how it behaves, how it is supposed to be used, and to do some first level of testing. I don't know about you guys, but I cannot develop without that. Rspec and unit testing have limits, even more so with the arcane error messages that Rspec throws at you when you do anything wrong.
That's what I use RSpec for. To document how the code is supposed to be used and, for the same price, to make sure the code is indeed executed on every submission (not only encouraged to be executed for others reading the example). For me, reading the Yardoc documentation and the RSpec tests is usually enough to make my mind and jump into development. So, somehow, for me the RSpec tests play the role of those examples. They contain the four (or more) lines I need to initialize the class in several concrete situations, a good overview of the supported scenarios... Everything I would need as an example and hopefully up to date (since they are actually executed in a regular basis, unlike the example scripts).
How can we get there? Don't you have the same problems? How do you develop code that will live in the inst-sys?
TBH, I don't feel I have the same problem. A said, it usually it takes me some minutes to reproduce the problem in a lightweight testing environment (a RSpec test or an example script) using Yardoc and RSpec as source of information for that. Of course, I still do the DUD thingy at the end (after fixing the stuff in that testing environment) to make sure everything works for real... and sometimes to find out further problems. :-(
I suggest we set up a Jangouts call to discuss this.
Fine for me. Any proposal? Cheers. -- Ancor González Sosa YaST Team at SUSE Linux GmbH -- To unsubscribe, e-mail: yast-devel+unsubscribe@opensuse.org To contact the owner, e-mail: yast-devel+owner@opensuse.org