Чи унікальність компонентів ПЗ є причиною його складності?

Я часто на своїх лекціях розповідаю студентам, що програмне забезпечення є найскладнішим інженерним творінням людини. Я, звісно, досі у цьому переконаний, але після декількох тривалих дискусій зі своїм студентом-дипломником похитнувся мій основний аргумент: у програмного забезпечення усі компоненти унікальні. Я завзято пояснював, що якщо з’являються два однакові шматки коду, то їх виносять у окрему підпрограму, залишаючи тільки виклик на старому місці. У той час електричний ланцюг може складатися з багатьох компонентів, що мають однакову функціональність: транзистори, резистори, конденсатори. Але чи доцільна така аналогія? Мабуть, коли мова заходить про компонент та про екземпляр компонента, це майже у всіх викликає замішання. І тут порівняння підпрограми з транзистором вкрай невдале, тому, що підпрограма є компонентом, а ось транзистор у мікросхемі є екземпляром компонента. Навряд чи хтось прагнутиме дублювати специфікацію транзистора, яка репрезентує абстрактне поняття компонента-транзистора. В свою чергу підпрограма багато разів ініціюється комп’ютером, який в залежності від виконуваної підпрограми-специфікації “прикидається” різними екземплярами компонентів. Насмілюся зробити висновок, що самі по собі компоненти унікальні в усіх інженерних галузях. Напевно замість згаданого аргументу слід говорити про те, що компонентів (“класів” компонентів) у програмному забезпеченні набагато більше ніж у інших творіннях людини, плюс до всього, кожен екземпляр компоненту може бути у величезній кількості станів. Можна сказати, що транзистор, у принципі, може знаходитись взагалі у нескінченній кількості станів, проте вони обумовлені законами фізики, а стани програмного забезпечення цілком визначають люди. А це вкрай складно.


C# vs JavaScript for Selenium tests

A few weeks ago I had a choice to be made and this choice was not easy for me. Here I would like to share my decision and some reasoning behind. I have decided to add some automated GUI testing to the project I am working on. This is a web application and therefore, the choice of the testing tool was simple – Selenium. However, I could not decide which language to use for coding the tests and testing framework. The thing is that I am currently bilingual guy (as probably every non-Node web developer) and I regularly use both C# and JavaScript. So I started coding first tests and inception of the test framework in both. After few days of coding using each language, I have finally chosen C# over JavaScript. Let me tell why and probably my reasoning will help someone else to make a decision.

I have started with JavaScript (Node, Jasmine, WebDriverJs, VS Code). Well, because:

  • Traditionally people write tests in scripting languages, which should add to the productivity and code simplicity
  • Node is true cross platform technology and if needed I would be able to run tests on any platform I like
  • I wanted to learn how to code for Node (doing modules and stuff)

At first, everything went well and smoothly, but then problems started to creep in. The root of these problems was JavaScript’s Selenium library asynchronous nature while tests are synchronous by nature. Test steps must execute sequentially because order matters. Perform “Save” button click before the form is filled and the test is miserably failed. Here are the problems:

  • Whole WebDriverJS API is asynchronous and every command results in a promise! Promise! Well, they are meant to be a simplification of callbacks, but they are still callbacks and for a sequential guy like me, haveing a promise after every API call is too much. To simulate synchronous test execution they use the ControlFlow library, which implicitly synchronizes asynchronous actions, making it so you only have to register a promise callback when you want to catch an error or access a return value. The brain just explodes. But it is just testing! It should be simple to be valuable. Resulted code with promises just promised to become maintenance nightmare;

  • Sometimes tests did not work as expected and I had to debug. You know, just put a breakpoint in the place where some call to web driver API happens. Like here, say, right before clicking the button:

But you know what? When execution stops at the breakpoint it is basically the middle of registration of callbacks. You are stopped even before Selenium started to search for “inputEmail”! I just can’t imagine where to put a breakpoint to have the test stop right before clicking the button (probably there is some way to do it but I don’t know it)

  • In the test itself, I did not want to use any variables for simplicity sake. So that business analyst or QA guy could easily understand what happens in the test. However because of
    promises I just had to introduce a variable and complexity, because there was no way to ensure that test assertion happened in the very end of the test:

While the code is probably not very complex, but it is definitely not for non-programmers.

  • Since Javascript is dynamic and WebDriverJS API is also dynamic, while coding you should constantly look at documentation or run debugger to see what kind of methods are available and how to call them correctly

After some fight, I gave up and started to do the same with C#. Wow! It was a just different world, all these problems were gone. Static typing gave fantastic auto-completion, debugging was just great! I could stop the test at any place and then go through it step by step observing the effects in the browser. Because there was no need to deal with promises while asserting, I was able to write test without variables:

Conclusion: sometimes your language and its library are not suitable for the task. Although I really like JavaScript (good parts) and it shines in the browser it turned out it is not the best option for doing test automation. Did I discover Atwood’s Law break? 🙂

Atwood’s Law: any application that can be written in JavaScript, will eventually be written in JavaScript.


Using the archive of the web

Do you want to have a really amazing tool under your belt? No problems! Just have a look at https://archive.org/web/. This is an archive of hundreds of billions of web pages. You can select whatever page you want to retrieve from the archive and then select restore point which is appropriate for your task.

Having this tool you can stop worrying that you can lose some information if your site goes down or hosting provider goes down or whatever happens. Let me give you two examples how I was using it.

First, I had a customer, whose site I needed to update and move to WordPress. Of course, I did a backup, but when I finished an update, backup version did not work properly. I had two options: either go and fix minor things to have the backup working fine or just go to the web archive. I went to the web archive and it was close to the miracle, there were many restore points which I could select and enjoy.

Second, I had another domain for my personal web stuff named alexnechay.com. I stopped paying for the hosting and provider switched it off. No worries for me, at that point I had my current domain, nechai.net, and I was blogging there. But later I wanted to add some information to my new site which was on alexnechay.com, switched off many months ago. Web archive just helped out. The domain name was entered and snapshot date was selected:

And here we go! This is how my website looked on 1-st of August 2015: