Index: twisted/web/test/test_xml.py
===================================================================
--- twisted/web/test/test_xml.py	(revision 25488)
+++ twisted/web/test/test_xml.py	(working copy)
@@ -350,6 +350,8 @@
         self.assertEquals(d.firstChild(), t)
         self.assert_(d.isEqualToNode(d2))
 
+        self.assertRaises(ValueError, d.replaceChild, t, d1)
+
     def testSearch(self):
         s = "<foo><bar id='me' /><baz><foo /></baz></foo>"
         s2 = "<fOo><bAr id='me' /><bAz><fOO /></bAz></fOo>"
@@ -788,6 +790,26 @@
         another.firstChild().appendChild(microdom.Node(object()))
         self.assertTrue(node.isEqualToNode(another))
 
+    def test_validChildInstance(self):
+        """
+        Children of L{Node} instances must also be L{Node} instances.
+        """
+        node = microdom.Node(object())
+        child = microdom.Node(object())
+        # Node.appendChild() only accepts Node instances.
+        node.appendChild(child)
+        self.assertRaises(TypeError, node.appendChild, None)
+        # Node.insertBefore() only accepts Node instances.
+        self.assertRaises(TypeError, node.insertBefore, child, None)
+        self.assertRaises(TypeError, node.insertBefore, None, child)
+        self.assertRaises(TypeError, node.insertBefore, None, None)
+        # Node.removeChild() only accepts Node instances.
+        node.removeChild(child)
+        self.assertRaises(TypeError, node.removeChild, None)
+        # Node.replaceChild() only accepts Node instances.
+        self.assertRaises(TypeError, node.replaceChild, child, None)
+        self.assertRaises(TypeError, node.replaceChild, None, child)
+        self.assertRaises(TypeError, node.replaceChild, None, None)
 
 
 class DocumentTests(TestCase):
Index: twisted/web/microdom.py
===================================================================
--- twisted/web/microdom.py	(revision 25488)
+++ twisted/web/microdom.py	(working copy)
@@ -158,29 +158,49 @@
             return 0
 
     def appendChild(self, child):
-        assert isinstance(child, Node)
+        """
+        @raise TypeError: If C{child} is not a C{Node} instance.
+        """
+        if not isinstance(child, Node):
+            raise TypeError("expected Node instance")
         self.childNodes.append(child)
         child.parentNode = self
 
     def insertBefore(self, new, ref):
+        """
+        @raise TypeError: If C{new} or C{ref} is not a C{Node} instance.
+        """
+        if not isinstance(new, Node) or not isinstance(ref, Node):
+            raise TypeError("expected Node instance")
         i = self.childNodes.index(ref)
         new.parentNode = self
         self.childNodes.insert(i, new)
         return new
 
     def removeChild(self, child):
+        """
+        @raise TypeError: If C{child} is not a C{Node} instance.
+        """
+        if not isinstance(child, Node):
+            raise TypeError("expected Node instance")
         if child in self.childNodes:
             self.childNodes.remove(child)
             child.parentNode = None
         return child
 
     def replaceChild(self, newChild, oldChild):
-        assert isinstance(newChild, Node)
+        """
+        @raise TypeError: If C{newChild} or C{oldChild} is not a C{Node}
+            instance.
+
+        @raise ValueError: If C{oldChild} is not a child of this C{Node}.
+        """
+        if not isinstance(newChild, Node) or not isinstance(oldChild, Node):
+            raise TypeError("expected Node instance")
         #if newChild.parentNode:
         #    newChild.parentNode.removeChild(newChild)
-        assert (oldChild.parentNode is self,
-                ('oldChild (%s): oldChild.parentNode (%s) != self (%s)'
-                 % (oldChild, oldChild.parentNode, self)))
+        if not oldChild.parentNode is self:
+            raise ValueError("oldChild is not a child of this node")
         self.childNodes[self.childNodes.index(oldChild)] = newChild
         oldChild.parentNode = None
         newChild.parentNode = self
@@ -232,9 +252,9 @@
         return self.childNodes[0]
     documentElement=property(get_documentElement)
 
-    def appendChild(self, c):
+    def appendChild(self, child):
         assert not self.childNodes, "Only one element per document."
-        Node.appendChild(self, c)
+        Node.appendChild(self, child)
 
     def writexml(self, stream, indent='', addindent='', newl='', strip=0,
                  nsprefixes={}, namespace=''):
