code: def test_basic(self):
      a = QN("a")
      self.assertEqual(a.qn, ("a",))
      self.assertEqual(str(a), "a")
      self.assertEqual(a.ssf(), "a")
      self.assertEqual(a.ast().id, "a")
      self.assertFalse(a.is_composite())
      with self.assertRaises(ValueError):
          _ = a.parent
  
      a_b = QN(a, attr="b")
      self.assertEqual(a_b.qn, (a, "b"))
      self.assertEqual(str(a_b), "a.b")
      self.assertEqual(a_b.ssf(), "a_b")
      self.assertEqual(a_b.ast().value.id, "a")
      self.assertEqual(a_b.ast().attr, "b")
      self.assertTrue(a_b.is_composite())
      self.assertEqual(a_b.parent.qn, ("a",))
  
imports: import textwrap
  from tensorflow.python.autograph.pyct import anno
  from tensorflow.python.autograph.pyct import parser
  from tensorflow.python.autograph.pyct import qual_names
  from tensorflow.python.autograph.pyct.qual_names import QN
  from tensorflow.python.autograph.pyct.qual_names import resolve
  from tensorflow.python.platform import test
label_desc: Use image node_id 2 for calling the QNTest obj's underlying member method code with example usage: obj.test_basic() without return types