diff --git a/qa/qa_config.py b/qa/qa_config.py
index d879d2df347dab772ca768d59e700ae1f1fe329f..664baace9c252ca98ff7392e05f75be67e95bdce 100644
--- a/qa/qa_config.py
+++ b/qa/qa_config.py
@@ -70,6 +70,17 @@ class _QaInstance(object):
 
     return cls(name=data["name"], nicmac=nicmac)
 
+  def __repr__(self):
+    status = [
+      "%s.%s" % (self.__class__.__module__, self.__class__.__name__),
+      "name=%s" % self.name,
+      "nicmac=%s" % self.nicmac,
+      "used=%s" % self._used,
+      "disk_template=%s" % self._disk_template,
+      ]
+
+    return "<%s at %#x>" % (" ".join(status), id(self))
+
   def Use(self):
     """Marks instance as being in use.
 
@@ -150,6 +161,17 @@ class _QaNode(object):
     """
     return cls(primary=data["primary"], secondary=data.get("secondary"))
 
+  def __repr__(self):
+    status = [
+      "%s.%s" % (self.__class__.__module__, self.__class__.__name__),
+      "primary=%s" % self.primary,
+      "secondary=%s" % self.secondary,
+      "added=%s" % self._added,
+      "use_count=%s" % self._use_count,
+      ]
+
+    return "<%s at %#x>" % (" ".join(status), id(self))
+
   def Use(self):
     """Marks a node as being in use.
 
diff --git a/test/py/qa.qa_config_unittest.py b/test/py/qa.qa_config_unittest.py
index b3e4b58c3d5144d44273285c04ce09276c91034a..ce987f887b3cb3272e0304ef8850dad9bb83d315 100755
--- a/test/py/qa.qa_config_unittest.py
+++ b/test/py/qa.qa_config_unittest.py
@@ -350,5 +350,59 @@ class TestQaConfig(unittest.TestCase):
                       exclude=acquired, _cfg=self.config)
 
 
+class TestRepresentation(unittest.TestCase):
+  def _Check(self, target, part):
+    self.assertTrue(part in repr(target).split())
+
+  def testQaInstance(self):
+    inst = qa_config._QaInstance("inst1.example.com", [])
+    self._Check(inst, "name=inst1.example.com")
+    self._Check(inst, "nicmac=[]")
+
+    # Default values
+    self._Check(inst, "disk_template=None")
+    self._Check(inst, "used=None")
+
+    # Use instance
+    inst.Use()
+    self._Check(inst, "used=True")
+
+    # Disk template
+    inst.SetDiskTemplate(constants.DT_DRBD8)
+    self._Check(inst, "disk_template=%s" % constants.DT_DRBD8)
+
+    # Release instance
+    inst.Release()
+    self._Check(inst, "used=False")
+    self._Check(inst, "disk_template=None")
+
+  def testQaNode(self):
+    node = qa_config._QaNode("primary.example.com", "192.0.2.1")
+    self._Check(node, "primary=primary.example.com")
+    self._Check(node, "secondary=192.0.2.1")
+    self._Check(node, "added=False")
+    self._Check(node, "use_count=0")
+
+    # Mark as added
+    node.MarkAdded()
+    self._Check(node, "added=True")
+
+    # Use node
+    for i in range(1, 5):
+      node.Use()
+      self._Check(node, "use_count=%s" % i)
+
+    # Release node
+    for i in reversed(range(1, 5)):
+      node.Release()
+      self._Check(node, "use_count=%s" % (i - 1))
+
+    self._Check(node, "use_count=0")
+
+    # Mark as added
+    node.MarkRemoved()
+    self._Check(node, "added=False")
+
+
 if __name__ == "__main__":
   testutils.GanetiTestProgram()