A day in the life of Squeak TDD
Last updated at 3:05 pm UTC on 22 June 2019
See also Basic Squeak Development Tools and Tinderbox
Keith Fieldhouse asked on December 08, 2005: I'm still having trouble "getting" what application development looks like when using Squeak. I understand the Smalltalk language reasonably well. .. I also understand that image based development is fundamentally different than file based development as it exists with most languages ... What I still can't quite understand is what an application development cycle looks like from idea to distributable application.
Here's what I think of when I consider application development in other environments. ... I'm trying
to relate Squeak development to what I already know. So, when I start an application in another language I:
1. Create a directory in which I'll keep the files related to the new application. There's a good chance that this directory will be near some other code that I use in the form of libraries).
2. Create a sub-directory in which I'll keep unit tests using some sort of unit test framework like JUnit.
3. I'll "write the tests first"
4. I'll write some code for my application, probably driving a "spike" through it's functionality in order to get at least one test to pass.
5. I'll run my tests. This involves starting the application from a known state (no objects instanced yet, for example), starting some portion of the application and running it.
6. Once I've got something to work, I'll check all of the code in my working directory into some sort of Source control system (probably Subversion) and continue to write code, checking.
7. I'll periodically run my application to see how its working from a user perspective. Generally that application starts from a known state and at a known entry point. The start up state may differ slightly based on saved information.
8. Eventually, I'll be done and I'll deploy the application. Generally I'll use some tool (Ant build files, Python setup files) to build the release. I'll generally test the deployed release in a "fresh" environment to duplication a potential user's experience.
So, given the above framework of a developer's day, what would the corresponding day look like with Squeak? Feel free to point me to other discussions or documentation. As I said, I've gotten hints about much of the above but I'm trying to synthesis it into the whole "story".
From the sound of you post, you are well versed in TDD. For some more insight in working in Squeak and Smalltalk in general, have a look at the original XP rules on the C3 project http://www.xprogramming.com/Practices/xpractices.htm, especially the ones about the Smalltalk development environment, i.e.
- Do it in an inspector
- No, do it in a workspace
- No, do it in an object
- Just set the halt (See below)
- Let Smalltalk tell you (See below)
They will give you some ideas about how to leverage image based development. These rules also give hints as to how TDD came about.
When partnering with Kent Beck, most everyone has this experience: Something goes wrong. The code doesnít work. You start to think: "What could cause that to happen?" Kent doesnít think about what the problem is. He just sets a halt in the system and lets Smalltalk tell him what the problem is.
- Donít Think, Just Set the Halt
Sometimes youíre right about what the problem is. If youíre really quick youíll be able to tell Kent what to edit in the window heís already looking at. If youíre really quick.
Sometimes youíre not right about what the problem is. Forget it, he has already fixed it.
Train yourself to think about where to put the halt, not to think about what the problem is. Of course itís a great feeling when you can reason to the problem. But weíre not here to make our brains feel good, weíre here to get the code working as quickly as possible. Setting the halt and letting Smalltalk tell you will help you build working code faster.
Hereís another guideline that is very easy to forget, but very important. The general notion is that Smalltalk is very good at incrementally changing things, breakpointing, and checking values. Instead of wasting time thinking about what to do, or theorizing about what went wrong, just ask Smalltalk. Here are some examples:
To work out some new capability,
- inspect an object,
- browse the class if you need to,
- then send the object messages,
- building the code you need right in the Inspector workspace. Then copy the code to an appropriate method.
When working on a new feature, donít implement all the necessary methods on all the objects you use. Instead, wait for the walkback for a method you havenít defined. Then go to the browser, implement the method, and proceed from the walkback.
Kent calls this "just-in-time programming".)
Smalltalk is keeping track of the order in which you need to do things.
When the system breaks, donít theorize: put in a breakpoint and step through the code until you see what is wrong. Youíll find the answer much faster.>>
Some context is missing here. Need to find this is split this off into another page Brad Fuller wrote: What you really do when you add a Package is add a Category, right? Categories are arbitrary. If you add VMMaker-Plugins you get all of the classes in the category, right? I just want to save my one class from that category, I don't want to save all of them. What am I missing?
Yanni Chiu What you're missing is that a Monticello package is merely a naming convention for class categories. IIUC, the approach is one of "The Simplest Thing That Could Possibly Work. The approach has proved to go a long way, but it won't handle what you're trying to do.
You seem to be separating the package concept from the class category. They are separate concepts, and most other packaging systems maintain the separation throughout the implementation as well. But that is not the case with Monticello. Maybe what you want to do is to introduce a package for an interface layer, and put your single class in that package. Then you can change the implementation and dependencies of the interface package, without affecting your higher level package. If this doesn't suit, then more explanation is needed of what you're trying to achieve with your packaging.
Hernan Tylim I think that what you are missing is a little of context. Very long before Monticello existed, Squeak package management was centered on class categories. On that time, developers by convention used the class categories as if they where packages. So you didn't create packages. What you did was to create class categories and put the classes on there and file-in and out the entire categories. Later, when DVS came to life (DVS is Monticello's ancestor), Avi and Julian (the creators of DVS and Monticello) decided that for packages they were gonna use the same concept that historically was being used for Packages on Squeak, the class categories.
Now. Answering to your question. You can't make that a class that belongs to another class category be part of your package. That class only belongs to the package where it is defined. If you have a package that depends on that class then your package depends on the other class' package as well, and you can't escape to that.
One thing that you might be able to do is to move out the classes that you are interested in into a new package, and make the other 2 dependants of the new one. (like class refactorings).
Bert Freudenberg responded to the above: Actually, you can ["make that a class that belongs to another class category be part of your package"]. Monticello does not look at class categories or method categories to determine what classes and methods are in a certain package. Rather, it looks up a PackageInfo instance by package name, and asks it for a list of classes and methods. Now, by default, such a PackageInfo instance is created on the fly,and when asked for its list of classes and methods it does pattern-matching on the system's categeories. However, it's entirely possible to provide your own PackageInfo subclass that uses different means of retrieving the list of classes. Like, simply by storing an explicit list. The advantage of the generic PackageInfo is that you define packages in the normal SystemBrowser by naming categories. ...a nice user interface for defining and editing such packages is in Alexandre Bergel's MonticelloPackageBrowser: http://kilana.unibe.ch/monticellopackagebrowser/
Yanni Chiu How do you avoid a tug-of-war over which package "owns" a class. If the shared class is in a package which uses the class category to determine its classes, and another package (through its PackageInfo) also assert ownership of that shared class, then both packages with save it out. When loading, the last one to load will overwrite the first one. When first saved out, the classes would be identical, but if they then take different development streams, then there's going to be a problem at some point.
Julian Fitzell Yup, that's largely why the default implementation of PackageInfo uses the class categories to define packages: each class has only one.