Turning unreasonable anxiety into unlikely ideas

Category: code

minimal desktop

Minimal Desktop

I code on an Ubuntu VM running on Windows. The Ubuntu VM is just for coding, I prefer to keep it small, which makes cloning and snapshots faster. Too many snapshots have caused problems for me. I delete the older ones, which again, is faster for smaller VM.

So, I started creating a minimal Python dev environment. First, I thought of using Emacs only. But I like PyCharm a lot, it ships with Emacs keymap. Between several terminal sessions, I needed at least two GUI apps: IDE & Chrome.

For terminal sessions, I started using tmux, which is great. PyCharm also has a terminal tab but you can’t switch to it and back to editor screen smoothly. It is not a first-class citizen like the editor window.

Enter xmonad, which helps you get rid of all the desktop items. It tiles windows occupying the whole screen. No dock, toolbar or OS menus. Now, I manage desktop with xmonad and terminal sessions with tmux. Here’s how I set it up on Ubuntu:

sudo apt-get install tmux
sudo apt-get install xmonad

Configure xmonad. The official docs are simple enough to get started. To launch PyCharm you’ll need wmname.

sudo apt-get install wmname

Now, log-off and select xmonad to log-in

After login you’ll be greeted with a blank screen. Fear not and open a terminal.
Start a tmux session:
tmux new -s session-name

tmux lets you launch multiple windows and panes. Perhaps, avoid tmux panes and create multiple session using xmonad windows, if needed. Also, xmonad allows you to configure tiling algorithms.

tmux command are followed by a prefix  (default is is Ctrl-b, configure if you want)

Open a new terminal window:
Ctrl-b C

Now, you can launch Pycharm using:
wmname LG3D && ./pycharm.sh

Create as many windows as you want. Once you’re done, use the xmonad to switch to your IDE.

The problem is getting used to different keybindings. You can easily configure keybindings as needed. Once you are habitual, you’ll stop using the mouse.





xmonad and PyCharm

Test Automation

Test Automation with Selenium

When learning Selenium, we start with tutorials which use a Login page example. It demonstrates the capabilities and show how to use them. When working on a project, it takes a while to figure out the structure so as to keep it manageable. Complexity increases as timelines get strict. To catch up with changes, teams devise different approaches. Here, I will describe one such approach. The focus is on Separation of Concerns and DRY.

Selenium supports many languages. All examples here use Java and TestNG. I assume you have gone through the basics.

It pays to start with an automation framework that covers common interactions in the application adhering to the DRY principle. Adding new tests becomes easier and faster. This is different from testing frameworks (JUnit/TestNG). Automation framework focuses on the tasks not verification.

If individual tests are hard to refactor then rot creeps in. It is important how we organize the test code. One useful pattern for Selenium is PageObject . It helps to separate automation code from tests.

Tests should be readable. Using the language of the domain helps. I am not talking about DSLs here. For example, the intent of a method called addItemToCart is clearer than clickButton So, it pays to keep the test methods short and clear.

Coming back to the Login page tutorial. At the end of it you have a single class with tests and automation methods. Let us split it and organize the code.

1. First, create a PageObject and move all the interactions in it. Define web elements (buttons, checkboxes etc) and locators (XPaths, CSS) here. Consider a shopping cart. The test should not bother about how to add items to the cart. Its purpose is to verify. So, the test should have access to a method like addItemToCart implemented by the PageObject. Suppose if the location of the button is changed, then tests need not be changed. Only addItemToCart is changed.

2. Suppose, you want to run loginTest with multiple combinations of usernames and passwords. For tests to be parameterized, create Data Providers. You will put data combinations here. Now, you can add test cases without touching the test method. Just append items to this data provider.

3. Create test suites which contain JUnit/TestNG classes. Now is a good time to think about a BaseTest class. Future tests can be derived from it. For example, if each test must login, then instead of repeating the @BeforeClass method, place it in BaseTest.

We have the following project structure:


  • Page Objects
  • Data Providers


  • Test Suites

So that should be good for a start. I’ll elaborate on the code with example in another post.

Powered by WordPress & Theme by Anders Norén